Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10528762
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Subscribers
None
View Options
diff --git a/less/prose-editor.less b/less/prose-editor.less
index fc8e8ba..768c078 100644
--- a/less/prose-editor.less
+++ b/less/prose-editor.less
@@ -1,452 +1,453 @@
body#pad.classic {
header {
display: flex;
justify-content: space-between;
align-items: center;
}
#editor {
top: 4em;
}
#title {
top: 4.25rem;
bottom: unset;
height: auto;
font-weight: bold;
font-size: 2em;
padding-top: 0;
padding-bottom: 0;
border: 0;
}
#tools {
#belt {
float: none;
}
}
#target {
ul {
a {
padding: 0 0.5em !important;
}
}
}
}
.ProseMirror {
position: relative;
height: calc(~"100% - 1.6em");
overflow-y: auto;
box-sizing: border-box;
-moz-box-sizing: border-box;
font-size: 1.2em;
word-wrap: break-word;
white-space: pre-wrap;
-webkit-font-variant-ligatures: none;
font-variant-ligatures: none;
padding: 0.5em 0;
line-height: 1.5;
outline: none;
}
.ProseMirror pre {
white-space: pre-wrap;
}
.ProseMirror li {
position: relative;
}
.ProseMirror-hideselection *::selection {
background: transparent;
}
.ProseMirror-hideselection *::-moz-selection {
background: transparent;
}
.ProseMirror-hideselection {
caret-color: transparent;
}
.ProseMirror-selectednode {
outline: 2px solid #8cf;
}
/* Make sure li selections wrap around markers */
li.ProseMirror-selectednode {
outline: none;
}
li.ProseMirror-selectednode:after {
content: "";
position: absolute;
left: -32px;
right: -2px;
top: -2px;
bottom: -2px;
border: 2px solid #8cf;
pointer-events: none;
}
.ProseMirror-textblock-dropdown {
min-width: 3em;
}
.ProseMirror-menu {
margin: 0 -4px;
line-height: 1;
}
.ProseMirror-tooltip .ProseMirror-menu {
width: -webkit-fit-content;
width: fit-content;
white-space: pre;
}
.ProseMirror-menuitem {
margin-right: 3px;
display: inline-block;
div {
cursor: pointer;
}
}
.ProseMirror-menuseparator {
border-right: 1px solid #ddd;
margin-right: 3px;
}
.ProseMirror-menu-dropdown, .ProseMirror-menu-dropdown-menu {
font-size: 90%;
white-space: nowrap;
}
.ProseMirror-menu-dropdown {
vertical-align: 1px;
cursor: pointer;
position: relative;
padding-right: 15px;
}
.ProseMirror-menu-dropdown-wrap {
padding: 1px 0 1px 4px;
display: inline-block;
position: relative;
}
.ProseMirror-menu-dropdown:after {
content: "";
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid currentColor;
opacity: .6;
position: absolute;
right: 4px;
top: calc(50% - 2px);
}
.ProseMirror-menu-dropdown-menu, .ProseMirror-menu-submenu {
position: absolute;
background: white;
color: #666;
border: 1px solid #aaa;
padding: 2px;
}
.ProseMirror-menu-dropdown-menu {
z-index: 15;
min-width: 6em;
}
.ProseMirror-menu-dropdown-item {
cursor: pointer;
padding: 2px 8px 2px 4px;
}
.ProseMirror-menu-dropdown-item:hover {
background: #f2f2f2;
}
.ProseMirror-menu-submenu-wrap {
position: relative;
margin-right: -4px;
}
.ProseMirror-menu-submenu-label:after {
content: "";
border-top: 4px solid transparent;
border-bottom: 4px solid transparent;
border-left: 4px solid currentColor;
opacity: .6;
position: absolute;
right: 4px;
top: calc(50% - 4px);
}
.ProseMirror-menu-submenu {
display: none;
min-width: 4em;
left: 100%;
top: -3px;
}
.ProseMirror-menu-active {
background: #eee;
border-radius: 4px;
}
.ProseMirror-menu-active {
background: #eee;
border-radius: 4px;
}
.ProseMirror-menu-disabled {
opacity: .3;
}
.ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu, .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu {
display: block;
}
.ProseMirror-menubar {
position: relative;
min-height: 1em;
color: #666;
padding: 0.5em;
top: 0;
left: 0;
right: 0;
background: rgba(255, 255, 255, 0.8);
z-index: 10;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: visible;
}
.ProseMirror-icon {
display: inline-block;
line-height: .8;
vertical-align: -2px; /* Compensate for padding */
padding: 2px 8px;
cursor: pointer;
}
.ProseMirror-menu-disabled.ProseMirror-icon {
cursor: default;
}
.ProseMirror-icon svg {
fill: currentColor;
height: 1em;
}
.ProseMirror-icon span {
vertical-align: text-top;
}
.ProseMirror-gapcursor {
display: none;
pointer-events: none;
position: absolute;
}
.ProseMirror-gapcursor:after {
content: "";
display: block;
position: absolute;
top: -2px;
width: 20px;
border-top: 1px solid black;
animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
}
@keyframes ProseMirror-cursor-blink {
to {
visibility: hidden;
}
}
.ProseMirror-focused .ProseMirror-gapcursor {
display: block;
}
/* Add space around the hr to make clicking it easier */
.ProseMirror-example-setup-style hr {
padding: 4px 10px;
border: none;
margin: 1em 0;
background: initial;
}
.ProseMirror-example-setup-style hr:after {
content: "";
display: block;
height: 1px;
background-color: #ccc;
line-height: 2px;
}
.ProseMirror ul, .ProseMirror ol {
padding-left: 30px;
}
.ProseMirror blockquote {
padding-left: 1em;
- border-left: 3px solid #eee;
+ border-left: 4px solid #ddd;
+ color: #767676;
margin-left: 0;
margin-right: 0;
}
.ProseMirror-example-setup-style img {
cursor: default;
max-width: 100%;
}
.ProseMirror-prompt {
background: white;
padding: 1em;
border: 1px solid silver;
position: fixed;
border-radius: 0.25em;
z-index: 11;
box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2);
}
.ProseMirror-prompt h5 {
margin: 0 0 0.75em;
font-family: @sansFont;
font-size: 100%;
color: #444;
}
.ProseMirror-prompt input[type="text"],
.ProseMirror-prompt textarea {
background: #eee;
border: none;
outline: none;
}
.ProseMirror-prompt input[type="text"] {
margin: 0.25em 0;
}
.ProseMirror-prompt-close {
position: absolute;
left: 2px;
top: 1px;
color: #666;
border: none;
background: transparent;
padding: 0;
}
.ProseMirror-prompt-close:after {
content: "✕";
font-size: 12px;
}
.ProseMirror-invalid {
background: #ffc;
border: 1px solid #cc7;
border-radius: 4px;
padding: 5px 10px;
position: absolute;
min-width: 10em;
}
.ProseMirror-prompt-buttons {
margin-top: 5px;
display: none;
}
#editor, .editor {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: black;
background-clip: padding-box;
padding: 5px 0;
margin: 4em auto 23px auto;
}
.ProseMirror p:first-child,
.ProseMirror h1:first-child,
.ProseMirror h2:first-child,
.ProseMirror h3:first-child,
.ProseMirror h4:first-child,
.ProseMirror h5:first-child,
.ProseMirror h6:first-child {
margin-top: 10px;
}
.ProseMirror p {
margin-bottom: 1em;
}
textarea {
width: 100%;
height: 123px;
border: 1px solid silver;
box-sizing: border-box;
-moz-box-sizing: border-box;
padding: 3px 10px;
border: none;
outline: none;
font-family: inherit;
font-size: inherit;
}
.ProseMirror-menubar-wrapper {
height: 100%;
box-sizing: border-box;
}
.ProseMirror-menubar-wrapper, #markdown textarea {
display: block;
margin-bottom: 4px;
}
.editorreadmore {
color: @textLinkColor;
text-decoration: underline;
text-align: center;
width: 100%;
}
@media all and (min-width: 50em) {
#editor {
margin-left: 10%;
margin-right: 10%;
}
}
@media all and (min-width: 60em) {
#editor {
margin-left: 15%;
margin-right: 15%;
}
}
@media all and (min-width: 70em) {
#editor {
margin-left: 20%;
margin-right: 20%;
}
}
@media all and (min-width: 85em) {
#editor {
margin-left: 25%;
margin-right: 25%;
}
}
@media all and (min-width: 105em) {
#editor {
margin-left: 30%;
margin-right: 30%;
}
}
diff --git a/prose/markdownParser.js b/prose/markdownParser.js
index 1ee5a07..30669d9 100644
--- a/prose/markdownParser.js
+++ b/prose/markdownParser.js
@@ -1,57 +1,57 @@
import { MarkdownParser } from "prosemirror-markdown";
import markdownit from "markdown-it";
import { writeFreelySchema } from "./schema";
export const writeFreelyMarkdownParser = new MarkdownParser(
writeFreelySchema,
markdownit("commonmark", { html: true }),
{
- // blockquote: { block: "blockquote" },
+ blockquote: { block: "blockquote" },
paragraph: { block: "paragraph" },
list_item: { block: "list_item" },
bullet_list: { block: "bullet_list" },
ordered_list: {
block: "ordered_list",
getAttrs: (tok) => ({ order: +tok.attrGet("start") || 1 }),
},
heading: {
block: "heading",
getAttrs: (tok) => ({ level: +tok.tag.slice(1) }),
},
code_block: { block: "code_block", noCloseToken: true },
fence: {
block: "code_block",
getAttrs: (tok) => ({ params: tok.info || "" }),
noCloseToken: true,
},
hr: { node: "horizontal_rule" },
image: {
node: "image",
getAttrs: (tok) => ({
src: tok.attrGet("src"),
title: tok.attrGet("title") || null,
alt: (tok.children !== null && typeof tok.children[0] !== 'undefined' ? tok.children[0].content : null),
}),
},
hardbreak: { node: "hard_break" },
em: { mark: "em" },
strong: { mark: "strong" },
link: {
mark: "link",
getAttrs: (tok) => ({
href: tok.attrGet("href"),
title: tok.attrGet("title") || null,
}),
},
code_inline: { mark: "code", noCloseToken: true },
html_block: {
node: "readmore",
getAttrs(token) {
// TODO: Give different attributes depending on the token content
return {};
},
},
}
);
diff --git a/prose/markdownSerializer.js b/prose/markdownSerializer.js
index 9615633..6ccf6bc 100644
--- a/prose/markdownSerializer.js
+++ b/prose/markdownSerializer.js
@@ -1,128 +1,128 @@
import { MarkdownSerializer } from "prosemirror-markdown";
function backticksFor(node, side) {
const ticks = /`+/g;
let m;
let len = 0;
if (node.isText)
while ((m = ticks.exec(node.text))) len = Math.max(len, m[0].length);
let result = len > 0 && side > 0 ? " `" : "`";
for (let i = 0; i < len; i++) result += "`";
if (len > 0 && side < 0) result += " ";
return result;
}
function isPlainURL(link, parent, index, side) {
if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
const content = parent.child(index + (side < 0 ? -1 : 0));
if (
!content.isText ||
content.text != link.attrs.href ||
content.marks[content.marks.length - 1] != link
)
return false;
if (index == (side < 0 ? 1 : parent.childCount - 1)) return true;
const next = parent.child(index + (side < 0 ? -2 : 1));
return !link.isInSet(next.marks);
}
export const writeFreelyMarkdownSerializer = new MarkdownSerializer(
{
readmore(state, node) {
state.write("<!--more-->\n");
state.closeBlock(node);
},
- // blockquote(state, node) {
- // state.wrapBlock("> ", undefined, node, () => state.renderContent(node));
- // },
+ blockquote(state, node) {
+ state.wrapBlock("> ", null, node, () => state.renderContent(node));
+ },
code_block(state, node) {
state.write(`\`\`\`${node.attrs.params || ""}\n`);
state.text(node.textContent, false);
state.ensureNewLine();
state.write("```");
state.closeBlock(node);
},
heading(state, node) {
state.write(`${state.repeat("#", node.attrs.level)} `);
state.renderInline(node);
state.closeBlock(node);
},
horizontal_rule: function horizontal_rule(state, node) {
state.write(node.attrs.markup || "---");
state.closeBlock(node);
},
bullet_list(state, node) {
node.attrs.tight = true;
state.renderList(node, " ", () => `${node.attrs.bullet || "*"} `);
},
ordered_list(state, node) {
const start = node.attrs.order || 1;
const maxW = String(start + node.childCount - 1).length;
const space = state.repeat(" ", maxW + 2);
state.renderList(node, space, (i) => {
const nStr = String(start + i);
return `${state.repeat(" ", maxW - nStr.length) + nStr}. `;
});
},
list_item(state, node) {
state.renderContent(node);
},
paragraph(state, node) {
state.renderInline(node);
state.closeBlock(node);
},
image(state, node) {
state.write(
`}${
node.attrs.title ? ` ${state.quote(node.attrs.title)}` : ""
})`
);
},
hard_break(state, node, parent, index) {
for (let i = index + 1; i < parent.childCount; i += 1)
if (parent.child(i).type !== node.type) {
state.write("\\\n");
return;
}
},
text(state, node) {
state.text(node.text || "");
},
},
{
em: {
open: "*",
close: "*",
mixable: true,
expelEnclosingWhitespace: true,
},
strong: {
open: "**",
close: "**",
mixable: true,
expelEnclosingWhitespace: true,
},
link: {
open(_state, mark, parent, index) {
return isPlainURL(mark, parent, index, 1) ? "<" : "[";
},
close(state, mark, parent, index) {
return isPlainURL(mark, parent, index, -1)
? ">"
: `](${state.esc(mark.attrs.href)}${
mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ""
})`;
},
},
code: {
open(_state, _mark, parent, index) {
return backticksFor(parent.child(index), -1);
},
close(_state, _mark, parent, index) {
return backticksFor(parent.child(index - 1), 1);
},
escape: false,
},
}
);
diff --git a/prose/schema.js b/prose/schema.js
index 0a87662..eeebbd9 100644
--- a/prose/schema.js
+++ b/prose/schema.js
@@ -1,20 +1,19 @@
import { schema } from "prosemirror-markdown";
import { Schema } from "prosemirror-model";
export const writeFreelySchema = new Schema({
nodes: schema.spec.nodes
- .remove("blockquote")
.addToEnd("readmore", {
inline: false,
content: "",
group: "block",
draggable: true,
toDOM: (node) => [
"div",
{ class: "editorreadmore" },
"Read more...",
],
parseDOM: [{ tag: "div.editorreadmore" }],
}),
marks: schema.spec.marks,
});
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Apr 6, 3:03 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3187791
Attached To
rWF WriteFreely
Event Timeline
Log In to Comment