Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions packages/markdown-preview/lib/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ exports.toHTML = async function (text, filePath, grammar) {
const domFragment = chooseRender(text, filePath)
const div = document.createElement('div')
annotatePreElements(domFragment, getDefaultLanguageForGrammar(grammar))

// Mark each PRE element with a `data-serialized` attribute.
//
// This helps distinguish between a PRE in the preview pane (which we want to
// hide, since the read-only editor is shown in its place) and a PRE in the
// generated HTML (which we want to show, since there is no substitute
// element).
for (let pre of domFragment.querySelectorAll('pre')) {
pre.dataset.serialized = true
}

div.appendChild(domFragment)
document.body.appendChild(div)

Expand Down Expand Up @@ -373,19 +384,33 @@ function convertAtomEditorToStandardElement(editorElement, preElement) {
// In this code path, we're transplanting the highlighted editor HTML into
// the existing `pre` element, so we should empty its contents first.
preElement.innerHTML = ''
const done = () =>
editor.component.getNextUpdatePromise().then(function () {
for (const line of editorElement.querySelectorAll(
'.line:not(.dummy)'
)) {
let timeout
const done = () => {
let updated = false;
let proceed = function () {
clearTimeout(timeout)
for (const line of editorElement.querySelectorAll('.line:not(.dummy)')) {
const line2 = document.createElement('div')
line2.className = 'line'
line2.innerHTML = line.firstChild.innerHTML
preElement.appendChild(line2)
}
editorElement.remove()
updated = true
resolve()
})
}
editor.component.getNextUpdatePromise().then(proceed)

// Guard against the next component update not happening promptly — or
// not happening at all. This isn't the right fix, but as a workaround
// it'll do.
timeout = setTimeout(() => {
// If we haven't had an update yet, force one.
if (updated) return
editor.component.updateSync()
proceed()
}, 500)
}
const languageMode = editor.getBuffer().getLanguageMode()
if (languageMode.fullyTokenized || languageMode.tree) {
done()
Expand Down
5 changes: 4 additions & 1 deletion packages/markdown-preview/styles/markdown-preview.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

// Hide a `pre` that comes directly after an `atom-text-editor` because the
// `atom-text-editor` is the syntax-highlighted representation.
atom-text-editor + pre {
//
// When we generate HTML via “Copy HTML” or “Save as HTML,” we add an
// attribute to the PRE so that this style rule is neutralized.
atom-text-editor + pre:not([data-serialized]) {
display: none;
}

Expand Down
Loading