20 |
21 |
Bookmarks
22 |
{
25 | createBookmark(schemaAndLanguage)
26 | }}
27 | />
28 |
29 | {bookmarkedSchemaAndLanguages &&
30 | bookmarkedSchemaAndLanguages.map((item, index) => {
31 | return (
32 |
{
36 | destroyBookmark(index)
37 | }}
38 | />
39 | )
40 | })}
41 |
42 | )
43 | }
44 |
45 | export default Bookmarks
46 |
--------------------------------------------------------------------------------
/src/components/HighlightExecutor.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { SchemaAndLanguage } from '../models/SchemaAndLanguage'
3 | import colorSchemaList from '../consts/colorSchemalist'
4 | import languageList from '../consts/languagelist'
5 | import Select from './Select'
6 |
7 | interface Props {
8 | schemaAndLanguage: SchemaAndLanguage
9 | setColorSchema: (event) => void
10 | setLanguage: (event) => void
11 | }
12 |
13 | const runHighlight = (schemaAndLanguage: SchemaAndLanguage) => {
14 | parent.postMessage(
15 | { pluginMessage: { type: 'CHANGE_COLOR', schemaAndLanguage } },
16 | '*'
17 | )
18 | }
19 |
20 | const HighlightExecutor: React.FC
= ({
21 | schemaAndLanguage,
22 | setColorSchema,
23 | setLanguage,
24 | }: Props) => {
25 | return (
26 |
27 |
28 |
29 |
Color Schema
30 |
38 |
39 |
Language
40 |
48 |
49 |
57 |
58 | )
59 | }
60 |
61 | export default HighlightExecutor
62 |
--------------------------------------------------------------------------------
/src/components/ListItemBookmark.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { SchemaAndLanguage } from '../models/SchemaAndLanguage'
3 |
4 | interface Props {
5 | schemaAndLanguage: SchemaAndLanguage
6 | destroy: () => void
7 | }
8 |
9 | const runHighlight = (schemaAndLanguage: SchemaAndLanguage) => {
10 | parent.postMessage(
11 | { pluginMessage: { type: 'CHANGE_COLOR', schemaAndLanguage } },
12 | '*'
13 | )
14 | }
15 |
16 | const ListItemBookmark: React.FC = ({
17 | schemaAndLanguage,
18 | destroy,
19 | }: Props) => {
20 | return (
21 |
22 |
23 |
24 | {schemaAndLanguage.colorSchema}
25 |
26 | /
27 |
28 | {schemaAndLanguage.language}
29 |
30 |
31 |
32 |
33 |
{
35 | runHighlight(schemaAndLanguage)
36 | }}
37 | className="type type--neg-small-bold cursor"
38 | >
39 | Run
40 |
41 |
42 | {
45 | destroy()
46 | }}
47 | />
48 |
49 |
50 |
51 | )
52 | }
53 |
54 | export default ListItemBookmark
55 |
--------------------------------------------------------------------------------
/src/components/Select.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | interface Props {
4 | current: string
5 | collection: string[]
6 | onChange: (event) => void
7 | }
8 |
9 | const Select: React.FC
= ({ current, collection, onChange }: Props) => {
10 | return (
11 |
29 | )
30 | }
31 |
32 | export default Select
33 |
--------------------------------------------------------------------------------
/src/consts/colorSchemaList.ts:
--------------------------------------------------------------------------------
1 | const colorSchemaList = [
2 | 'a11yDark',
3 | 'a11yLight',
4 | 'agate',
5 | 'anOldHope',
6 | 'androidstudio',
7 | 'arduinoLight',
8 | 'arta',
9 | 'ascetic',
10 | 'atelierCaveDark',
11 | 'atelierCaveLight',
12 | 'atelierDuneDark',
13 | 'atelierDuneLight',
14 | 'atelierEstuaryDark',
15 | 'atelierEstuaryLight',
16 | 'atelierForestDark',
17 | 'atelierForestLight',
18 | 'atelierHeathDark',
19 | 'atelierHeathLight',
20 | 'atelierLakesideDark',
21 | 'atelierLakesideLight',
22 | 'atelierPlateauDark',
23 | 'atelierPlateauLight',
24 | 'atelierSavannaDark',
25 | 'atelierSavannaLight',
26 | 'atelierSeasideDark',
27 | 'atelierSeasideLight',
28 | 'atelierSulphurpoolDark',
29 | 'atelierSulphurpoolLight',
30 | 'atomOneDark',
31 | 'atomOneDarkReasonable',
32 | 'atomOneLight',
33 | 'brownPaper',
34 | 'codepenEmbed',
35 | 'colorBrewer',
36 | 'darcula',
37 | 'dark',
38 | 'defaultColor',
39 | 'docco',
40 | 'dracula',
41 | 'far',
42 | 'foundation',
43 | 'github',
44 | 'githubGist',
45 | 'gml',
46 | 'googlecode',
47 | 'gorilla',
48 | 'grayscale',
49 | 'gruvboxDark',
50 | 'gruvboxLight',
51 | 'hopscotch',
52 | 'hybrid',
53 | 'idea',
54 | 'irBlack',
55 | 'isblEditorDark',
56 | 'isblEditorLight',
57 | 'kimbieDark',
58 | 'kimbieLight',
59 | 'lightfair',
60 | 'magula',
61 | 'monoBlue',
62 | 'monokai',
63 | 'monokaiSublime',
64 | 'noctis',
65 | 'nord',
66 | 'obsidian',
67 | 'ocean',
68 | 'paraisoDark',
69 | 'paraisoLight',
70 | 'pojoaque',
71 | 'purebasic',
72 | 'qtcreatorDark',
73 | 'qtcreatorLight',
74 | 'railscasts',
75 | 'rainbow',
76 | 'routeros',
77 | 'schoolBook',
78 | 'shadesOfPurple',
79 | 'solarizedDark',
80 | 'solarizedLight',
81 | 'sunburst',
82 | 'tomorrow',
83 | 'tomorrowNight',
84 | 'tomorrowNightBlue',
85 | 'tomorrowNightBright',
86 | 'tomorrowNightEighties',
87 | 'vs',
88 | 'vs2015',
89 | 'xcode',
90 | 'xt256',
91 | 'zenburn',
92 | ]
93 |
94 | export default colorSchemaList
95 |
--------------------------------------------------------------------------------
/src/consts/languageList.ts:
--------------------------------------------------------------------------------
1 | const languageList = [
2 | '1c',
3 | 'abnf',
4 | 'accesslog',
5 | 'actionscript',
6 | 'ada',
7 | 'angelscript',
8 | 'apache',
9 | 'applescript',
10 | 'arcade',
11 | 'cpp',
12 | 'arduino',
13 | 'armasm',
14 | 'xml',
15 | 'asciidoc',
16 | 'aspectj',
17 | 'autohotkey',
18 | 'autoit',
19 | 'avrasm',
20 | 'awk',
21 | 'axapta',
22 | 'bash',
23 | 'basic',
24 | 'bnf',
25 | 'brainfuck',
26 | 'cal',
27 | 'capnproto',
28 | 'ceylon',
29 | 'clean',
30 | 'clojure',
31 | 'clojure-repl',
32 | 'cmake',
33 | 'coffeescript',
34 | 'coq',
35 | 'cos',
36 | 'crmsh',
37 | 'crystal',
38 | 'cs',
39 | 'csp',
40 | 'css',
41 | 'd',
42 | 'markdown',
43 | 'dart',
44 | 'delphi',
45 | 'diff',
46 | 'django',
47 | 'dns',
48 | 'dockerfile',
49 | 'dos',
50 | 'dsconfig',
51 | 'dts',
52 | 'dust',
53 | 'ebnf',
54 | 'elixir',
55 | 'elm',
56 | 'ruby',
57 | 'erb',
58 | 'erlang-repl',
59 | 'erlang',
60 | 'excel',
61 | 'fix',
62 | 'flix',
63 | 'fortran',
64 | 'fsharp',
65 | 'gams',
66 | 'gauss',
67 | 'gcode',
68 | 'gherkin',
69 | 'glsl',
70 | 'gml',
71 | 'go',
72 | 'golo',
73 | 'gradle',
74 | 'groovy',
75 | 'haml',
76 | 'handlebars',
77 | 'haskell',
78 | 'haxe',
79 | 'hsp',
80 | 'htmlbars',
81 | 'http',
82 | 'hy',
83 | 'inform7',
84 | 'ini',
85 | 'irpf90',
86 | 'isbl',
87 | 'java',
88 | 'javascript',
89 | 'jboss-cli',
90 | 'json',
91 | 'julia',
92 | 'julia-repl',
93 | 'kotlin',
94 | 'lasso',
95 | 'ldif',
96 | 'leaf',
97 | 'less',
98 | 'lisp',
99 | 'livecodeserver',
100 | 'livescript',
101 | 'llvm',
102 | 'lsl',
103 | 'lua',
104 | 'makefile',
105 | 'mathematica',
106 | 'matlab',
107 | 'maxima',
108 | 'mel',
109 | 'mercury',
110 | 'mipsasm',
111 | 'mizar',
112 | 'perl',
113 | 'mojolicious',
114 | 'monkey',
115 | 'moonscript',
116 | 'n1ql',
117 | 'nginx',
118 | 'nimrod',
119 | 'nix',
120 | 'nsis',
121 | 'objectivec',
122 | 'ocaml',
123 | 'openscad',
124 | 'oxygene',
125 | 'parser3',
126 | 'pf',
127 | 'pgsql',
128 | 'php',
129 | 'plaintext',
130 | 'pony',
131 | 'powershell',
132 | 'processing',
133 | 'profile',
134 | 'prolog',
135 | 'properties',
136 | 'protobuf',
137 | 'puppet',
138 | 'purebasic',
139 | 'python',
140 | 'q',
141 | 'qml',
142 | 'r',
143 | 'reasonml',
144 | 'rib',
145 | 'roboconf',
146 | 'routeros',
147 | 'rsl',
148 | 'ruleslanguage',
149 | 'rust',
150 | 'sas',
151 | 'scala',
152 | 'scheme',
153 | 'scilab',
154 | 'scss',
155 | 'shell',
156 | 'smali',
157 | 'smalltalk',
158 | 'sml',
159 | 'sqf',
160 | 'sql',
161 | 'stan',
162 | 'stata',
163 | 'step21',
164 | 'stylus',
165 | 'subunit',
166 | 'swift',
167 | 'taggerscript',
168 | 'yaml',
169 | 'tap',
170 | 'tcl',
171 | 'tex',
172 | 'thrift',
173 | 'tp',
174 | 'twig',
175 | 'typescript',
176 | 'vala',
177 | 'vbnet',
178 | 'vbscript',
179 | 'vbscript-html',
180 | 'verilog',
181 | 'vhdl',
182 | 'vim',
183 | 'x86asm',
184 | 'xl',
185 | 'xquery',
186 | 'zephir',
187 | ]
188 |
189 | export default languageList
190 |
--------------------------------------------------------------------------------
/src/models/SchemaAndLanguage.ts:
--------------------------------------------------------------------------------
1 | export interface SchemaAndLanguage {
2 | language: string
3 | colorSchema: string
4 | }
5 |
--------------------------------------------------------------------------------
/src/pages/Dashboard.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { useState, useEffect } from 'react'
3 | import Bookmarks from '../components/Bookmarks'
4 | import HighlightExecutor from '../components/HighlightExecutor'
5 |
6 | const Dashboard: React.FC = () => {
7 | const [schemaAndLanguage, setSchemaAndLanguage] = useState({
8 | language: '',
9 | colorSchema: '',
10 | })
11 |
12 | const [
13 | bookmarkedSchemaAndLanguages,
14 | setBookmarkedSchemaAndLanguages,
15 | ] = useState([])
16 |
17 | useEffect(() => {
18 | onmessage = event => {
19 | if (event.data.pluginMessage.type == 'CURRENT_SCHEMA_AND_LANGUAGE') {
20 | setSchemaAndLanguage(event.data.pluginMessage.schemaAndLanguage)
21 | }
22 |
23 | if (event.data.pluginMessage.type == 'BOOKMARKED_SCHEMA_AND_LANGUAGES') {
24 | setBookmarkedSchemaAndLanguages(array => [
25 | ...array,
26 | ...event.data.pluginMessage.schemaAndLanguages,
27 | ])
28 | }
29 | }
30 | })
31 |
32 | useEffect(() => {
33 | parent.postMessage(
34 | {
35 | pluginMessage: {
36 | type: 'UPDATE_BOOKMARKS',
37 | schemaAndLanguages: bookmarkedSchemaAndLanguages,
38 | },
39 | },
40 | '*'
41 | )
42 | }, [bookmarkedSchemaAndLanguages])
43 |
44 | return (
45 |
46 |
{
49 | setSchemaAndLanguage(
50 | Object.assign(schemaAndLanguage, {
51 | colorSchema: event.target.value,
52 | })
53 | )
54 | }}
55 | setLanguage={event => {
56 | setSchemaAndLanguage(
57 | Object.assign(schemaAndLanguage, {
58 | language: event.target.value,
59 | })
60 | )
61 | }}
62 | />
63 |
64 |
65 |
66 | {
70 | setBookmarkedSchemaAndLanguages(array => {
71 | const obj = Object.assign({}, schemaAndLanguage)
72 | return [obj, ...array]
73 | })
74 | }}
75 | destroyBookmark={index => {
76 | setBookmarkedSchemaAndLanguages(array => {
77 | array.splice(index, 1)
78 | return [...array]
79 | })
80 | }}
81 | />
82 |
83 | )
84 | }
85 |
86 | export default Dashboard
87 |
--------------------------------------------------------------------------------
/src/ui.css:
--------------------------------------------------------------------------------
1 | .box {
2 | margin: 8px 0 16px;
3 | }
4 |
5 | .flex {
6 | display: flex;
7 | padding-bottom: 8px;
8 | }
9 |
10 | .flexChild:first-child {
11 | width: 50%;
12 | padding-right: 4px;
13 | }
14 |
15 | .flexChild:last-child {
16 | width: 50%;
17 | padding-left: 4px;
18 | }
19 |
20 | .buttonFullWidth {
21 | display: block;
22 | width: 100%;
23 | }
24 |
25 | .boxPadding {
26 | padding: 16px 0;
27 | }
28 |
29 | .bookmarksSectionTitle {
30 | display: flex;
31 | justify-content: space-between;
32 | }
33 |
34 | .bookmarkListItem {
35 | display: flex;
36 | justify-content: space-between;
37 | align-items: center;
38 | padding: 0 0 0 8px;
39 | }
40 |
41 | .bookmarkListItemButtons {
42 | display: flex;
43 | align-items: center;
44 | }
45 |
46 | .cursor {
47 | cursor: pointer;
48 | }
49 |
--------------------------------------------------------------------------------
/src/ui.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/ui.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import * as ReactDOM from 'react-dom'
3 | import Dashboard from './pages/Dashboard'
4 | import './figma-plugin-ds.css'
5 | import './ui.css'
6 |
7 | declare function require(path: string): any
8 |
9 | class App extends React.Component {
10 | render() {
11 | return
12 | }
13 | }
14 |
15 | ReactDOM.render(, document.getElementById('react-page'))
16 |
--------------------------------------------------------------------------------
/src/usecases/changeColorUsecase.ts:
--------------------------------------------------------------------------------
1 | import { highlightAuto } from 'highlight.js'
2 | import * as colorSchema from '../assets/colorSchema/index'
3 | import { SchemaAndLanguage } from '../models/SchemaAndLanguage'
4 |
5 | const xpath = require('xpath')
6 | const dom = require('xmldom').DOMParser
7 |
8 | declare function require(path: string): any
9 |
10 | function* walkTree(node) {
11 | yield node
12 | let children = node.childNodes
13 | if (children) {
14 | for (let i = 0; i < children.length; i++) {
15 | yield* walkTree(children[i])
16 | }
17 | }
18 | }
19 |
20 | function countLength(node): number {
21 | let lng: number = 0
22 |
23 | if (node.childNodes) {
24 | /* ElementNode */
25 | for (let i = 0; i < node.childNodes.length; i++) {
26 | lng = lng + countLength(node.childNodes[i])
27 | }
28 | } else {
29 | /* TextNode */
30 | lng = lng + node.length
31 | }
32 |
33 | return lng
34 | }
35 |
36 | const changeColorUsecase = (
37 | selections: ReadonlyArray,
38 | schemaAndLanguage: SchemaAndLanguage
39 | ) => {
40 | selections.map(item => {
41 | if (item.type == 'TEXT') {
42 | let itm: TextNode = item
43 |
44 | const result = highlightAuto(itm.characters, [schemaAndLanguage.language])
45 | const str: string = `${result.value}
`
46 | const doc = new dom().parseFromString(str)
47 |
48 | let nodes = xpath.select('//div', doc)[0]
49 | let results = []
50 | let length: number = 0
51 |
52 | for (let i = 0; i < nodes.childNodes.length; i++) {
53 | let walker = walkTree(nodes.childNodes[i])
54 | let res
55 |
56 | while (!(res = walker.next()).done) {
57 | let node = res.value
58 |
59 | if (node.data) {
60 | length = length + node.length
61 | } else {
62 | results.push({
63 | length: countLength(node),
64 | lengthStart: length,
65 | lengthEnd: length + countLength(node),
66 | className: node.attributes[0].nodeValue,
67 | })
68 | }
69 | }
70 | }
71 | itm.setRangeFills(0, itm.characters.length, [
72 | colorSchema[schemaAndLanguage.colorSchema]['hljs'],
73 | ])
74 |
75 | results.map(res => {
76 | let color = colorSchema[schemaAndLanguage.colorSchema][res.className]
77 | color = color
78 | ? color
79 | : colorSchema[schemaAndLanguage.colorSchema]['hljs']
80 |
81 | itm.setRangeFills(res.lengthStart, res.lengthEnd, [color])
82 | })
83 | figma.notify('Completed.', { timeout: 1 })
84 | } else {
85 | figma.notify('Please select Textbox before running.')
86 | }
87 | })
88 |
89 | if (selections.length == 0) {
90 | figma.notify('Please select Textbox before running.')
91 | }
92 | }
93 |
94 | export default changeColorUsecase
95 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "jsx": "react",
5 | "typeRoots": ["./src/types"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackInlineSourcePlugin = require("html-webpack-inline-source-plugin");
2 | const HtmlWebpackPlugin = require("html-webpack-plugin");
3 | const path = require("path");
4 |
5 | module.exports = (env, argv) => ({
6 | mode: argv.mode === "production" ? "production" : "development",
7 |
8 | devtool: argv.mode === "production" ? false : "inline-source-map",
9 |
10 | entry: {
11 | ui: "./src/ui.tsx",
12 | code: "./src/code.ts"
13 | },
14 |
15 | module: {
16 | rules: [
17 | { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/ },
18 | {
19 | test: /\.css$/,
20 | loader: [{ loader: "style-loader" }, { loader: "css-loader" }]
21 | },
22 | { test: /\.(png|jpg|gif|webp|svg)$/, loader: [{ loader: "url-loader" }] }
23 | ]
24 | },
25 |
26 | resolve: { extensions: [".tsx", ".ts", ".jsx", ".js"] },
27 |
28 | output: {
29 | filename: "[name].js",
30 | path: path.resolve(__dirname, "dist")
31 | },
32 |
33 | plugins: [
34 | new HtmlWebpackPlugin({
35 | template: "./src/ui.html",
36 | filename: "ui.html",
37 | inlineSource: ".(js)$",
38 | chunks: ["ui"]
39 | }),
40 | new HtmlWebpackInlineSourcePlugin()
41 | ]
42 | });
43 |
--------------------------------------------------------------------------------