Files: 54f45b9e3a2114fd3c234a8de046349c9a3dab1c / src / components / SourceViewer.js
4552 bytesRaw
1 | import { highlight, languages } from 'prismjs'; |
2 | import { default as pull } from 'pull-stream' |
3 | import Util from '../Util.js'; |
4 | |
5 | class SourceViewer extends HTMLElement { |
6 | constructor() { |
7 | super(); |
8 | } |
9 | connectedCallback() { |
10 | const shadow = this.attachShadow({ mode: 'open' }); |
11 | shadow.innerHTML = ` |
12 | <link rel="stylesheet" href="/index.css"> |
13 | <style> |
14 | #source { |
15 | background: white; |
16 | opacity: 1; |
17 | height: 100%; |
18 | width: 100%; |
19 | max-height: 100%; |
20 | max-width: 100%; |
21 | overflow: auto; |
22 | padding: 8px; |
23 | } |
24 | |
25 | .id { |
26 | font-family: monospace; |
27 | font-size: 12px; |
28 | margin-bottom: 8px; |
29 | font-style: italic; |
30 | color: gray; |
31 | } |
32 | |
33 | .id::after { |
34 | content: ' is'; |
35 | color: #000000; |
36 | } |
37 | |
38 | #source .code { |
39 | width: min-content; |
40 | padding-right: 8px; |
41 | } |
42 | |
43 | pre { |
44 | margin: 0; |
45 | } |
46 | |
47 | /** |
48 | * prism.js default theme for JavaScript, CSS and HTML |
49 | * Based on dabblet (http://dabblet.com) |
50 | * @author Lea Verou |
51 | */ |
52 | |
53 | code[class*="language-"], |
54 | pre[class*="language-"] { |
55 | color: black; |
56 | background: none; |
57 | text-shadow: 0 1px white; |
58 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; |
59 | font-size: 1em; |
60 | text-align: left; |
61 | white-space: pre; |
62 | word-spacing: normal; |
63 | word-break: normal; |
64 | word-wrap: normal; |
65 | line-height: 1.5; |
66 | |
67 | -moz-tab-size: 4; |
68 | -o-tab-size: 4; |
69 | tab-size: 4; |
70 | |
71 | -webkit-hyphens: none; |
72 | -moz-hyphens: none; |
73 | -ms-hyphens: none; |
74 | hyphens: none; |
75 | } |
76 | |
77 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, |
78 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { |
79 | text-shadow: none; |
80 | background: #b3d4fc; |
81 | } |
82 | |
83 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, |
84 | code[class*="language-"]::selection, code[class*="language-"] ::selection { |
85 | text-shadow: none; |
86 | background: #b3d4fc; |
87 | } |
88 | |
89 | @media print { |
90 | code[class*="language-"], |
91 | pre[class*="language-"] { |
92 | text-shadow: none; |
93 | } |
94 | } |
95 | |
96 | /* Code blocks */ |
97 | pre[class*="language-"] { |
98 | padding: 1em; |
99 | margin: .5em 0; |
100 | overflow: auto; |
101 | } |
102 | |
103 | :not(pre) > code[class*="language-"], |
104 | pre[class*="language-"] { |
105 | background: #f5f2f0; |
106 | } |
107 | |
108 | /* Inline code */ |
109 | :not(pre) > code[class*="language-"] { |
110 | padding: .1em; |
111 | border-radius: .3em; |
112 | white-space: normal; |
113 | } |
114 | |
115 | .token.comment, |
116 | .token.prolog, |
117 | .token.doctype, |
118 | .token.cdata { |
119 | color: slategray; |
120 | } |
121 | |
122 | .token.punctuation { |
123 | color: #999; |
124 | } |
125 | |
126 | .token.namespace { |
127 | opacity: .7; |
128 | } |
129 | |
130 | .token.property, |
131 | .token.tag, |
132 | .token.boolean, |
133 | .token.number, |
134 | .token.constant, |
135 | .token.symbol, |
136 | .token.deleted { |
137 | color: #905; |
138 | } |
139 | |
140 | .token.selector, |
141 | .token.attr-name, |
142 | .token.string, |
143 | .token.char, |
144 | .token.builtin, |
145 | .token.inserted { |
146 | color: #690; |
147 | } |
148 | |
149 | .token.operator, |
150 | .token.entity, |
151 | .token.url, |
152 | .language-css .token.string, |
153 | .style .token.string { |
154 | color: #9a6e3a; |
155 | /* This background color was intended by the author of this theme. */ |
156 | /* background: hsla(0, 0%, 100%, .5); */ |
157 | } |
158 | |
159 | .token.atrule, |
160 | .token.attr-value, |
161 | .token.keyword { |
162 | color: #07a; |
163 | } |
164 | |
165 | .token.function, |
166 | .token.class-name { |
167 | color: #DD4A68; |
168 | } |
169 | |
170 | .token.regex, |
171 | .token.important, |
172 | .token.variable { |
173 | color: #e90; |
174 | } |
175 | |
176 | .token.important, |
177 | .token.bold { |
178 | font-weight: bold; |
179 | } |
180 | .token.italic { |
181 | font-style: italic; |
182 | } |
183 | |
184 | .token.entity { |
185 | cursor: help; |
186 | } |
187 | </style> |
188 | ` |
189 | shadow.innerHTML += ` |
190 | <header class="bar"> |
191 | <h1>Source of <span id="title-ext">${this.name}</span></h1> |
192 | <div class="icons"> |
193 | <button id="close"> |
194 | <svg width="24" viewBox="0 0 24 24"> |
195 | <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" /> |
196 | </svg> |
197 | </button> |
198 | </div> |
199 | </header> |
200 | ` |
201 | |
202 | |
203 | shadow.getElementById('close').addEventListener('click', () => { |
204 | this.dispatchEvent(new CustomEvent('close')) |
205 | }) |
206 | |
207 | const root = document.createElement('div') |
208 | shadow.appendChild(root) |
209 | root.id = 'source' |
210 | |
211 | const indicator = document.createElement('div') |
212 | root.appendChild(indicator) |
213 | indicator.classList.add('loading') |
214 | indicator.innerText = 'Loading...' |
215 | |
216 | const main = document.createElement('div') |
217 | root.appendChild(main) |
218 | main.classList.add('code') |
219 | const pre = document.createElement('pre') |
220 | main.appendChild(pre) |
221 | ;(new Util(this.sbot)).dereferenceUriOrSigil(this.app.link).then(code => { |
222 | pre.innerText = code |
223 | requestAnimationFrame(() => { |
224 | const html = this.app.type === 'patchboot-app' ? |
225 | highlight(code, languages.javascript, 'javascript') : |
226 | highlight(code, languages.html, 'html') |
227 | pre.innerHTML = html |
228 | }) |
229 | }) |
230 | } |
231 | } |
232 | |
233 | customElements.define("source-viewer", SourceViewer); |
Built with git-ssb-web