Skip to content
Merged
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
32 changes: 4 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
![](./images/flomo128.png)
原项目地址 https://github.com/greycodee/flomo-code

# Flomo Code
feat: 仅新增复制按钮

Flomo Code 是一款 Chrome 扩展程序,为您的 Flomo 笔记提供代码语法高亮功能。
feat: 新增自动高亮

## 安装

您可以从 [Release](https://github.com/greycodee/flomo-code/releases/) 下载源码压缩包,然后解压文件。在 **Chrome 扩展程序**页面打开右上角的**开发者模式**,选择**加载已解压的扩展程序**,选择解压的文件路径,就可加载flomo-code
## 使用

要使用 Flomo Code,只需在 Flomo 笔记中添加 Markdown 代码块,点击 flomo 页面右下角`绿色按钮`,即可突出显示语法。

### before
![](./before.png)

### after
![](./after.png)

## 更换代码主题

可以在插件栏点击进行更换代码主题

![](./choose_theme.gif)
## 贡献

欢迎贡献!如果您发现错误或有功能请求,请在 [GitHub 存储库](https://github.com/greycodee/flomo-code) 上打开 Issue。

## 许可证

Flomo Code 在 [MIT 许可证](https://opensource.org/licenses/MIT) 下获得许可。
fix: 网址形式的内容在高亮块显示不为 herf 问题
57 changes: 24 additions & 33 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
{
"name": "flomo code",
"version": "1.1",
"manifest_version": 3,
"description": "flomo md代码块高亮插件",
"action":{
"default_title":"选择主题",
"default_popup": "popup/popup.html"
},
"permissions": [
"storage",
"scripting",
"tabs",
"activeTab"
],
"background": {
"service_worker": "service-worker.js"
},
"icons": {
"name": "flomo code",
"version": "1.1",
"manifest_version": 3,
"description": "flomo md代码块高亮插件",
"action": {
"default_title": "选择主题",
"default_popup": "popup/popup.html"
},
"permissions": ["storage", "scripting", "tabs", "activeTab", "webRequest"],
"background": {
"service_worker": "service-worker.js"
},
"icons": {
"128": "images/flomo128.png"
},

"128": "images/flomo128.png"
},

"web_accessible_resources": [
{
"resources": ["images/*"],
"matches": ["https://v.flomoapp.com/*","https://flomoapp.com/*"]
}
],
"host_permissions": [
"https://v.flomoapp.com/*",
"https://flomoapp.com/*"
],
"options_page": "options/options.html"
}
"web_accessible_resources": [
{
"resources": ["images/*"],
"matches": ["https://v.flomoapp.com/*", "https://flomoapp.com/*", "https://h5.udrig.com/*"]
}
],
"host_permissions": ["https://v.flomoapp.com/*", "https://flomoapp.com/*", "https://h5.udrig.com/*"],
"options_page": "options/options.html"
}
232 changes: 162 additions & 70 deletions scripts/content.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,168 @@
window.onload = function () {
const hljsbtn = document.createElement("button");
const img = document.createElement("img");
img.src = chrome.runtime.getURL("images/code.svg");
img.style.height = "20px";
img.style.width = "20px";

hljsbtn.appendChild(img);

// hljsbtn.innerHTML = "点击";
hljsbtn.type = "button";
hljsbtn.style.height = "36px";
hljsbtn.style.width = "36px";
hljsbtn.style.borderRadius = "36px";
hljsbtn.style.border = "none";
hljsbtn.style.backgroundColor = "#397354";
hljsbtn.style.color = "#fff";
hljsbtn.style.cursor = "pointer";
hljsbtn.style.position = "fixed";
hljsbtn.style.bottom = "80px";
hljsbtn.style.right = "30px";
hljsbtn.style.zIndex = "9999";
hljsbtn.style.display = "flex";
hljsbtn.style.justifyContent = "center";
hljsbtn.style.alignItems = "center";

hljsbtn.addEventListener("click", () => {
const memos = document.getElementsByClassName("richText");
const hljsbtn = document.createElement('button');
const img = document.createElement('img');
img.src = chrome.runtime.getURL('images/code.svg');
img.style.height = '20px';
img.style.width = '20px';

hljsbtn.appendChild(img);

// hljsbtn.innerHTML = "点击";
hljsbtn.type = 'button';
hljsbtn.style.height = '36px';
hljsbtn.style.width = '36px';
hljsbtn.style.borderRadius = '36px';
hljsbtn.style.border = 'none';
hljsbtn.style.backgroundColor = '#397354';
hljsbtn.style.color = '#fff';
hljsbtn.style.cursor = 'pointer';
hljsbtn.style.position = 'fixed';
hljsbtn.style.bottom = '80px';
hljsbtn.style.right = '30px';
hljsbtn.style.zIndex = '9999';
hljsbtn.style.display = 'flex';
hljsbtn.style.justifyContent = 'center';
hljsbtn.style.alignItems = 'center';

hljsbtn.addEventListener('click', highlightCodeBlocks);

document.body.appendChild(hljsbtn);
};

// 添加消息监听器
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === 'highlightCode') {
highlightCodeBlocks();
sendResponse({ status: '高亮处理完成' });
}
return true; // 表示会异步发送响应
});

// 将代码高亮功能抽取为单独的函数
function highlightCodeBlocks() {
const memos = document.getElementsByClassName('richText');
const memos_array = Array.from(memos);
memos_array.forEach((memo) => {
let children = memo.children;
const memo_p_array = Array.from(children);
let languageFlag = false;
let codeContentArr = [];
let languageType = "";
for (let i = 0; i < memo_p_array.length; i++) {
if (
memo_p_array[i].innerHTML.startsWith("```") &&
memo_p_array[i].innerHTML.substring(3) != ""
) {
languageType = "language-" + memo_p_array[i].innerHTML.substring(3);
languageFlag = true;
memo.removeChild(memo_p_array[i]);
continue;
} else if (
memo_p_array[i].innerHTML.startsWith("```") &&
memo_p_array[i].innerHTML.substring(3) === ""
) {
// memo.removeChild(memo_p_array[i]);
languageFlag = false;
let pre = document.createElement("pre");
let code = document.createElement("code");
code.innerHTML = codeContentArr.join("\n");
code.className = languageType;
pre.appendChild(code);
memo_p_array[i].innerHTML = "";
memo_p_array[i].appendChild(pre);
// memo.appendChild(pre);
//清空数组
codeContentArr = [];
languageType = "";
continue;
} else {
if (languageFlag) {
codeContentArr.push(memo_p_array[i].innerHTML);
memo.removeChild(memo_p_array[i]);
}
let children = memo.children;
const memo_p_array = Array.from(children);
let languageFlag = false;
let codeContentArr = [];
let languageType = '';
for (let i = 0; i < memo_p_array.length; i++) {
if (memo_p_array[i].innerHTML.startsWith('```') && memo_p_array[i].innerHTML.substring(3) != '') {
languageType = 'language-' + memo_p_array[i].innerHTML.substring(3);
languageFlag = true;
memo.removeChild(memo_p_array[i]);
continue;
} else if (memo_p_array[i].innerHTML.startsWith('```') && memo_p_array[i].innerHTML.substring(3) === '') {
// memo.removeChild(memo_p_array[i]);
languageFlag = false;

// 保存代码内容的副本用于复制功能
const codeForCopy = [...codeContentArr];

let pre = document.createElement('pre');
let code = document.createElement('code');
code.innerHTML = codeContentArr.join('\n');
code.className = languageType;

let wrapper = document.createElement('div');
wrapper.style.position = 'relative';

// 创建复制按钮
let copyBtn = document.createElement('button');
copyBtn.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" 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>';
copyBtn.style.position = 'absolute';
copyBtn.style.top = '5px';
copyBtn.style.right = '5px';
copyBtn.style.zIndex = '100';
copyBtn.style.fontSize = '12px';
copyBtn.style.padding = '4px';
copyBtn.style.background = 'rgba(240, 240, 240, 0.8)';
copyBtn.style.border = '1px solid #ccc';
copyBtn.style.borderRadius = '3px';
copyBtn.style.cursor = 'pointer';
copyBtn.style.display = 'flex';
copyBtn.style.justifyContent = 'center';
copyBtn.style.alignItems = 'center';
copyBtn.title = '复制代码';

copyBtn.addEventListener('click', function (e) {
e.stopPropagation();

// 创建临时元素解码HTML
const tempElement = document.createElement('div');

// 处理内容
let decodedContent = [];
for (let i = 0; i < codeForCopy.length; i++) {
tempElement.innerHTML = codeForCopy[i];
decodedContent.push(tempElement.textContent || tempElement.innerText);
}

// 最终复制内容
const codeText = decodedContent.join('\n');

// 复制到剪贴板
navigator.clipboard
.writeText(codeText)
.then(() => {
copyBtn.style.color = '#4CAF50';
copyBtn.title = '已复制!';

setTimeout(() => {
copyBtn.style.color = '';
copyBtn.title = '复制代码';
}, 1500);
})
.catch((err) => {
console.error('复制失败:', err);
});
});

pre.appendChild(code);
wrapper.appendChild(pre);
wrapper.appendChild(copyBtn);

memo_p_array[i].innerHTML = '';
memo_p_array[i].appendChild(wrapper);
// memo.appendChild(pre);
//清空数组
codeContentArr = [];
languageType = '';
continue;
} else {
if (languageFlag) {
// 处理内容中的a标签
let content = memo_p_array[i].innerHTML;

// 创建临时DOM元素来解析HTML
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content;

// 查找所有a标签
const links = tempDiv.querySelectorAll('a');
links.forEach((link) => {
// 获取href属性
const href = link.getAttribute('href');
if (href) {
// 替换整个a标签为@+href
const linkText = `${href}`;
// 创建文本节点
const textNode = document.createTextNode(linkText);
// 替换a标签为文本节点
link.parentNode.replaceChild(textNode, link);
}
});

// 获取处理后的内容
content = tempDiv.innerHTML;
codeContentArr.push(content);
memo.removeChild(memo_p_array[i]);
}
}
}
}
});
hljs.highlightAll();
});
document.body.appendChild(hljsbtn);


};
}
Loading