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
36 changes: 22 additions & 14 deletions background/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,30 @@ md.messages = ({storage: {defaults, state, set}, compilers, mathjax, xhr, webreq
})
}
else if (req.message === 'prism') {
chrome.scripting.executeScript({
target: {tabId: sender.tab.id},
files: [
`/vendor/prism/prism-${req.language}.min.js`,
],
injectImmediately: true
}, sendResponse)
if (sender.tab) {
chrome.scripting.executeScript({
target: {tabId: sender.tab.id},
files: [
`/vendor/prism/prism-${req.language}.min.js`,
],
injectImmediately: true
}, sendResponse)
} else {
sendResponse()
}
}
else if (req.message === 'mathjax') {
chrome.scripting.executeScript({
target: {tabId: sender.tab.id},
files: [
`/vendor/mathjax/extensions/${req.extension}.js`,
],
injectImmediately: true
}, sendResponse)
if (sender.tab) {
chrome.scripting.executeScript({
target: {tabId: sender.tab.id},
files: [
`/vendor/mathjax/extensions/${req.extension}.js`,
],
injectImmediately: true
}, sendResponse)
} else {
sendResponse()
}
}

// popup
Expand Down
17 changes: 13 additions & 4 deletions background/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,19 @@ md.storage.bug = (res) => {
// reload extension bug
chrome.permissions.getAll((permissions) => {
var origins = Object.keys(res.origins || {})
chrome.permissions.remove({
origins: permissions.origins
.filter((origin) => origins.indexOf(origin.slice(0, -2)) === -1)
})
var originsToRemove = (permissions.origins || [])
.filter((origin) => origins.indexOf(origin.slice(0, -2)) === -1)
if (originsToRemove.length) {
var promise = chrome.permissions.remove({
origins: originsToRemove
}, () => {
// Ignore error when trying to remove required permissions
var error = chrome.runtime.lastError
})
if (promise && promise.catch) {
promise.catch(() => {})
}
}
})
}

Expand Down
98 changes: 98 additions & 0 deletions content/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,101 @@ img.emojione {
/* prevent img stretch */
width: auto;
}

/*---------------------------------------------------------------------------*/
/*copy button*/

#_html pre {
position: relative;
}

#_html pre .markdown-copy-button {
position: absolute;
top: 8px;
right: 8px;
opacity: 0;
transition: opacity 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
border: 1px solid var(--copy-btn-border);
background-color: var(--copy-btn-bg);
color: var(--copy-btn-color);
padding: 6px;
border-radius: 6px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
user-select: none;
-webkit-user-select: none;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

/* Show button on pre hover and focus */
#_html pre:hover .markdown-copy-button,
#_html pre .markdown-copy-button:focus {
opacity: 1;
}

#_html pre .markdown-copy-button:hover {
background-color: var(--copy-btn-bg-hover);
border-color: var(--copy-btn-border-hover);
color: var(--copy-btn-color-hover);
}

#_html pre .markdown-copy-button.copied {
background-color: var(--copy-btn-bg-copied);
border-color: var(--copy-btn-border-copied);
color: var(--copy-btn-color-copied);
}

/* Base Theme Variables */
body {
--copy-btn-bg: rgba(255, 255, 255, 0.85);
--copy-btn-bg-hover: rgba(240, 240, 240, 0.95);
--copy-btn-border: #e1e4e8;
--copy-btn-border-hover: #b0b5bc;
--copy-btn-color: #57606a;
--copy-btn-color-hover: #24292f;
--copy-btn-bg-copied: #dcffe4;
--copy-btn-border-copied: #85e89d;
--copy-btn-color-copied: #22863a;
}

@media (prefers-color-scheme: dark) {
body {
--copy-btn-bg: rgba(33, 38, 45, 0.85);
--copy-btn-bg-hover: rgba(48, 54, 61, 0.95);
--copy-btn-border: #30363d;
--copy-btn-border-hover: #8b949e;
--copy-btn-color: #8b949e;
--copy-btn-color-hover: #c9d1d9;
--copy-btn-bg-copied: rgba(56, 139, 253, 0.15);
--copy-btn-border-copied: rgba(56, 139, 253, 0.4);
--copy-btn-color-copied: #58a6ff;
}
}

._color-light {
--copy-btn-bg: rgba(255, 255, 255, 0.85);
--copy-btn-bg-hover: rgba(240, 240, 240, 0.95);
--copy-btn-border: #e1e4e8;
--copy-btn-border-hover: #b0b5bc;
--copy-btn-color: #57606a;
--copy-btn-color-hover: #24292f;
--copy-btn-bg-copied: #dcffe4;
--copy-btn-border-copied: #85e89d;
--copy-btn-color-copied: #22863a;
}

._color-dark {
--copy-btn-bg: rgba(33, 38, 45, 0.85);
--copy-btn-bg-hover: rgba(48, 54, 61, 0.95);
--copy-btn-border: #30363d;
--copy-btn-border-hover: #8b949e;
--copy-btn-color: #8b949e;
--copy-btn-color-hover: #c9d1d9;
--copy-btn-bg-copied: rgba(56, 139, 253, 0.15);
--copy-btn-border-copied: rgba(56, 139, 253, 0.4);
--copy-btn-color-copied: #58a6ff;
}

53 changes: 53 additions & 0 deletions content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,59 @@ var update = (update) => {
if (state.content.mathjax) {
setTimeout(() => mj.render(), 60)
}

setTimeout(() => addCopyButtons(), 80)
}

var addCopyButtons = () => {
var preElements = document.querySelectorAll('#_html pre')
preElements.forEach((pre) => {
if (pre.querySelector('code.mermaid') || pre.querySelector('svg[id^=mermaid]')) {
return
}
if (pre.querySelector('.markdown-copy-button')) {
return
}

var button = document.createElement('button')
button.className = 'markdown-copy-button'
button.type = 'button'
button.title = 'Copy code'
button.setAttribute('aria-label', 'Copy code')

button.innerHTML = `
<svg class="copy-icon" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
<svg class="check-icon" viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="display: none;">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
`

button.addEventListener('click', () => {
var codeElement = pre.querySelector('code')
var text = codeElement ? codeElement.innerText : pre.innerText

navigator.clipboard.writeText(text).then(() => {
var copyIcon = button.querySelector('.copy-icon')
var checkIcon = button.querySelector('.check-icon')
copyIcon.style.display = 'none'
checkIcon.style.display = 'inline'
button.classList.add('copied')

setTimeout(() => {
copyIcon.style.display = 'inline'
checkIcon.style.display = 'none'
button.classList.remove('copied')
}, 2000)
}).catch((err) => {
console.error('Failed to copy text: ', err)
})
})

pre.appendChild(button)
})
}

var render = (md) => {
Expand Down
21 changes: 16 additions & 5 deletions content/mathjax.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@ var MathJax = {
pathFilters: [
({name}) => name.startsWith('[tex]') ? false : true // keep the name
],
require: (path) => path.startsWith('[tex]') ?
chrome.runtime.sendMessage({
message: 'mathjax',
extension: path.replace('[tex]/', '')
}) : null
require: (path) => {
if (path.startsWith('[tex]')) {
var extension = path.replace('[tex]/', '')
if (location.protocol.endsWith('-extension:')) {
var script = document.createElement('script')
script.src = `/vendor/mathjax/extensions/${extension}.js`
document.body.appendChild(script)
return null
}
return chrome.runtime.sendMessage({
message: 'mathjax',
extension
})
}
return null
}
},
tex: {
inlineMath: [
Expand Down
17 changes: 17 additions & 0 deletions content/preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Markdown Preview</title>
<style>
#source-markdown {
display: none;
}
</style>
</head>
<body>
<pre id="source-markdown"></pre>
<script src="/content/preview.js"></script>
</body>
</html>
75 changes: 75 additions & 0 deletions content/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
;(async () => {
const localData = await chrome.storage.local.get('temporaryMarkdown')
const markdown = localData.temporaryMarkdown || ''

const pre = document.querySelector('pre')
pre.textContent = markdown

const state = await chrome.storage.sync.get()

window.args = {
theme: state.theme,
raw: state.raw,
themes: state.themes,
content: state.content,
compiler: state.compiler,
custom: state.custom,
icon: state.settings.icon,
}

const loadCSS = (href) => {
return new Promise((resolve) => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.type = 'text/css'
link.href = href
link.onload = resolve
document.head.appendChild(link)
})
}

const loadScript = (src) => {
return new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = src
script.onload = resolve
script.onerror = reject
document.body.appendChild(script)
})
}

await Promise.all([
loadCSS('/content/index.css'),
loadCSS('/content/themes.css')
])

await loadScript('/vendor/mithril.min.js')

if (window.args.content.syntax) {
await loadScript('/vendor/prism.min.js')
await loadScript('/vendor/prism-autoloader.min.js')
await loadScript('/content/prism.js')
}

if (window.args.content.emoji) {
await loadScript('/content/emoji.js')
}

if (window.args.content.mermaid) {
await loadScript('/vendor/mermaid.min.js')
await loadScript('/vendor/panzoom.min.js')
await loadScript('/content/mermaid.js')
}

if (window.args.content.mathjax) {
await loadScript('/content/mathjax.js')
await loadScript('/vendor/mathjax/tex-mml-chtml.js')
}

await loadScript('/content/index.js')
await loadScript('/content/scroll.js')

if (window.args.content.autoreload) {
await loadScript('/content/autoreload.js')
}
})()
17 changes: 13 additions & 4 deletions content/prism.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@

Prism.plugins.autoloader.addScript = (language, done) => {
chrome.runtime.sendMessage({
message: 'prism',
language
}, done)
if (location.protocol.endsWith('-extension:')) {
var script = document.createElement('script')
script.src = `/vendor/prism/prism-${language}.min.js`
script.onload = () => done()
script.onerror = () => done()
document.body.appendChild(script)
}
else {
chrome.runtime.sendMessage({
message: 'prism',
language
}, done)
}
}
3 changes: 2 additions & 1 deletion manifest.chrome.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

"permissions": [
"storage",
"scripting"
"scripting",
"activeTab"
],

"host_permissions": [
Expand Down
3 changes: 2 additions & 1 deletion manifest.firefox.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@

"permissions": [
"storage",
"scripting"
"scripting",
"activeTab"
],

"host_permissions": [
Expand Down
Loading