Skip to content

Commit 2d45818

Browse files
authored
v0.0.6 - 코드 하이라이팅 기능 (#12)
* chore: v0.0.6으로 업데이트 * chore: highlight.js 설치 * feat(popup): 소스코드 블럭에 코드 하이라이팅 추가 * fix(getLanguageByFileName): filename 없을 때, 얼리 리턴 처리 * feat(popup): 확장자 안내 메시지 추가
1 parent f2c8389 commit 2d45818

File tree

6 files changed

+254
-33
lines changed

6 files changed

+254
-33
lines changed

package-lock.json

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codezap-chrome-extension",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"description": "코드잽 크롬 익스텐션입니다",
55
"scripts": {
66
"start": "webpack --watch --progress --config webpack.dev.js",
@@ -24,5 +24,8 @@
2424
"webpack-cli": "^5.1.4"
2525
},
2626
"author": "jayMyong66",
27-
"license": "MIT"
27+
"license": "MIT",
28+
"dependencies": {
29+
"highlight.js": "^11.10.0"
30+
}
2831
}

src/popup/popup.module.css

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,31 @@
169169

170170
background-color: white;
171171
}
172+
173+
.sourceCodeWrapper {
174+
width: 300px;
175+
border: 1px solid black;
176+
border-top: 0;
177+
border-radius: 0 0 4px 4px;
178+
padding: 8px;
179+
}
180+
181+
.pre {
182+
overflow-x: auto;
183+
overflow-y: hidden;
184+
max-width: 100%;
185+
text-indent: 0;
186+
}
187+
188+
.codeBlock {
189+
cursor: auto;
190+
text-indent: 0;
191+
}
192+
193+
.filenameMessage {
194+
width: 100%;
195+
display: flex;
196+
justify-content: flex-end;
197+
font-size: 10px;
198+
color: #393e46;
199+
}

src/popup/popup.tsx

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import styles from './popup.module.css';
2828
import '../styles/reset.css';
2929
import VisibilityToggle from '../components/VisibilityToggle/VisibilityToggle';
3030
import { urlToDescription } from '../utils/urlToDescription';
31+
import hljs from 'highlight.js';
32+
import 'highlight.js/styles/github.css';
33+
import { getLanguageByFilename } from '../utils/getLanguageByFileName';
3134

3235
const Popup = () => {
3336
const [userInfo, setUserInfo] = useState<UserInfo>({
@@ -112,17 +115,11 @@ const Popup = () => {
112115
loadCategories(memberId);
113116
alert('로그인에 성공했어요!');
114117
// 추가
115-
console.log('here ', name, memberId);
116-
chrome.runtime.sendMessage(
117-
{
118-
action: 'sendUserInfo',
119-
name,
120-
memberId,
121-
},
122-
(response) => {
123-
console.log('send message response', response);
124-
}
125-
);
118+
chrome.runtime.sendMessage({
119+
action: 'sendUserInfo',
120+
name,
121+
memberId,
122+
});
126123
// 끝
127124
} catch (error) {
128125
console.error('로그인 에러: ', error);
@@ -333,20 +330,28 @@ const Popup = () => {
333330
toggleVisibility={toggleVisibility}
334331
/>
335332
</div>
336-
<div className={styles.checkboxContainer}>
337-
<label className={styles.checkboxLabel}>
338-
<input
339-
type='checkbox'
340-
className={styles.checkboxInput}
341-
checked={attachUrl}
342-
onChange={handleCheckboxChange}
343-
/>
344-
<span className={styles.checkboxText}>출처 url 첨부</span>
345-
</label>
333+
<div style={{ width: '100%' }}>
334+
<div className={styles.checkboxContainer}>
335+
<label className={styles.checkboxLabel}>
336+
<input
337+
type='checkbox'
338+
className={styles.checkboxInput}
339+
checked={attachUrl}
340+
onChange={handleCheckboxChange}
341+
/>
342+
<span className={styles.checkboxText}>출처 url 첨부</span>
343+
</label>
344+
</div>
345+
{sourceCodes.length !== 0 && (
346+
<div className={styles.filenameMessage}>
347+
확장자를 입력하면 코드 스타일이 생겨요
348+
</div>
349+
)}
346350
</div>
347351
{sourceCodes.length === 0 && (
348352
<div>원하는 소스코드를 드래그 후 우클릭 하여 추가해보세요</div>
349353
)}
354+
350355
{sourceCodes.map((code, index) => (
351356
<div key={index} className={styles.sourceCodeContainer}>
352357
<input
@@ -356,13 +361,19 @@ const Popup = () => {
356361
value={fileNames[index]}
357362
onChange={(e) => handleFileNameChange(index, e.target.value)}
358363
/>
359-
<textarea
360-
readOnly
361-
value={code}
362-
rows={4}
363-
cols={35}
364-
className={styles.sourceCodeTextArea}
365-
/>
364+
<div className={styles.sourceCodeWrapper}>
365+
<pre className={styles.pre}>
366+
<code
367+
className={styles.codeBlock}
368+
dangerouslySetInnerHTML={{
369+
__html: hljs.highlight(code, {
370+
language: getLanguageByFilename(fileNames[index]),
371+
}).value,
372+
}}
373+
/>
374+
</pre>
375+
</div>
376+
366377
<button
367378
onClick={() => handleRemoveSourceCode(index)}
368379
className={styles.removeButton}

src/static/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "코드잽 익스텐션",
4-
"version": "0.0.5",
4+
"version": "0.0.6",
55
"description": "코드잽 템플릿 업로드를 도와주는 익스텐션입니다.",
66
"permissions": ["contextMenus", "storage", "scripting", "activeTab"],
77
"host_permissions": ["https://code-zap.com/*", "https://www.code-zap.com/*"],

src/utils/getLanguageByFileName.ts

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
export const getLanguageByFilename = (filename: string) => {
2+
const extension = getFileExtension(filename);
3+
const language = getLanguageByExtension(extension);
4+
5+
return language;
6+
};
7+
8+
export const getLanguageForAutoTag = (filename: string) => {
9+
const extension = getFileExtension(filename);
10+
const language = getLanguageByExtension(extension);
11+
12+
if (extension === 'jsx' || extension === 'tsx') {
13+
return 'react';
14+
}
15+
16+
if (language === 'plaintext') {
17+
return '';
18+
}
19+
20+
return language;
21+
};
22+
23+
const getFileExtension = (filename: string) => {
24+
if (!filename) {
25+
return '';
26+
}
27+
if (filename.includes('.')) {
28+
const parts = filename.split('.');
29+
30+
return parts.pop() || '';
31+
}
32+
33+
return '';
34+
};
35+
36+
const getLanguageByExtension = (extension: string) =>
37+
extensionToLanguage[extension] || 'plaintext';
38+
39+
const extensionToLanguage: { [key: string]: string } = {
40+
'1c': '1c',
41+
adoc: 'asciidoc',
42+
ado: 'stata',
43+
adb: 'ada',
44+
ads: 'ada',
45+
applescript: 'applescript',
46+
as: 'actionscript',
47+
asc: 'asciidoc',
48+
asm: 'x86asm',
49+
asp: 'asp',
50+
awk: 'awk',
51+
bash: 'bash',
52+
bas: 'basic',
53+
bat: 'dos',
54+
bf: 'brainfuck',
55+
bmx: 'blitzmax',
56+
boo: 'boo',
57+
c: 'c',
58+
cbl: 'cobol',
59+
cc: 'cpp',
60+
clj: 'clojure',
61+
cls: 'cos',
62+
cmake: 'cmake',
63+
coffee: 'coffeescript',
64+
cpp: 'cpp',
65+
hpp: 'cpp',
66+
cr: 'crystal',
67+
cs: 'csharp',
68+
css: 'css',
69+
cxx: 'cpp',
70+
d: 'd',
71+
dart: 'dart',
72+
dcl: 'clean',
73+
dfm: 'delphi',
74+
dpr: 'delphi',
75+
druby: 'ruby',
76+
dsconfig: 'dsconfig',
77+
dts: 'dts',
78+
ecl: 'ecl',
79+
elm: 'elm',
80+
erl: 'erlang',
81+
ex: 'elixir',
82+
exs: 'elixir',
83+
f90: 'fortran',
84+
for: 'fortran',
85+
frag: 'glsl',
86+
fs: 'fsharp',
87+
gemspec: 'ruby',
88+
glsl: 'glsl',
89+
go: 'go',
90+
gql: 'graphql',
91+
gradle: 'gradle',
92+
graphql: 'graphql',
93+
groovy: 'groovy',
94+
haml: 'haml',
95+
hbs: 'handlebars',
96+
hcl: 'hcl',
97+
hlsl: 'hlsl',
98+
hs: 'haskell',
99+
html: 'html',
100+
hx: 'haxe',
101+
hxx: 'cpp',
102+
iced: 'iced',
103+
idl: 'idl',
104+
ini: 'ini',
105+
ino: 'arduino',
106+
i7x: 'inform7',
107+
ipynb: 'python',
108+
java: 'java',
109+
jl: 'julia',
110+
js: 'javascript',
111+
jsx: 'javascript',
112+
kt: 'kotlin',
113+
less: 'less',
114+
lhs: 'haskell',
115+
lisp: 'lisp',
116+
lock: 'yaml',
117+
lua: 'lua',
118+
m: 'objectivec',
119+
mak: 'makefile',
120+
markdown: 'markdown',
121+
md: 'markdown',
122+
mk: 'makefile',
123+
ml: 'ocaml',
124+
mli: 'ocaml',
125+
ms: 'javascript',
126+
nix: 'nix',
127+
nsi: 'nsis',
128+
nsh: 'nsis',
129+
nu: 'nu',
130+
php: 'php',
131+
pl: 'perl',
132+
pm: 'perl',
133+
pyd: 'python',
134+
py: 'python',
135+
r: 'r',
136+
rake: 'ruby',
137+
rb: 'ruby',
138+
rhtml: 'erb',
139+
rs: 'rust',
140+
rss: 'xml',
141+
sass: 'sass',
142+
scala: 'scala',
143+
scss: 'scss',
144+
sh: 'shell',
145+
sls: 'yaml',
146+
spec: 'ruby',
147+
sql: 'sql',
148+
styl: 'stylus',
149+
swift: 'swift',
150+
tex: 'latex',
151+
thor: 'ruby',
152+
toml: 'toml',
153+
ts: 'typescript',
154+
tsx: 'typescript',
155+
txt: 'plaintext',
156+
vala: 'vala',
157+
vb: 'vbnet',
158+
vbs: 'vbscript',
159+
vh: 'verilog',
160+
vhdl: 'vhdl',
161+
vim: 'vim',
162+
vue: 'vue',
163+
xhtml: 'xml',
164+
xml: 'xml',
165+
xquery: 'xquery',
166+
yml: 'yaml',
167+
zep: 'zephir',
168+
};

0 commit comments

Comments
 (0)