diff --git a/package-lock.json b/package-lock.json
index b81c7c0..b70878b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2384,6 +2384,12 @@
"minimalistic-assert": "^1.0.0"
}
},
+ "detect-browser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npm.taobao.org/detect-browser/download/detect-browser-4.8.0.tgz",
+ "integrity": "sha1-HXO9iMF76GaQGVDOCqrh7QYJAsY=",
+ "dev": true
+ },
"detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
diff --git a/package.json b/package.json
index a13ec8f..f380459 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"coffee-loader": "^0.9.0",
"coffeescript": "^2.5.1",
"css-loader": "^3.4.2",
+ "detect-browser": "^4.8.0",
"fast-xml-parser": "^3.16.0",
"highlight.js": "^9.18.1",
"html-webpack-inline-source-plugin": "0.0.10",
diff --git a/src/index.coffee b/src/index.coffee
index b5d6200..cf20d21 100644
--- a/src/index.coffee
+++ b/src/index.coffee
@@ -21,15 +21,18 @@ buildInvalidResponse = (msg) ->
new Response msg,
status: 400
+buildFrontendResponse = ->
+ new Response indexHtml,
+ status: 200
+ headers:
+ 'content-type': 'text/html'
+
handleRequest = (event) ->
# Handle request for static home page first
if event.request.method == "GET"
parsedURL = new URL event.request.url
if parsedURL.pathname in FRONTEND_PATHS
- return new Response indexHtml,
- status: 200
- headers:
- 'content-type': 'text/html'
+ return buildFrontendResponse _
# Validate file name first, since this is shared logic
file = util.getFileName event.request.url
@@ -99,6 +102,14 @@ handleGET = (req, file) ->
return new Response "Something went wrong",
status: resp.status
+ # If the content is text, and the user is using a browser
+ # show frontend code viewer
+ if not req.url.endsWith 'original'
+ isText = util.isText resp.headers.get 'content-type'
+ isBrowser = util.isBrowser req
+ if isText and isBrowser
+ return buildFrontendResponse _
+
# Build response headers
headers =
'content-length': resp.headers.get 'content-length'
diff --git a/src/util.coffee b/src/util.coffee
index 24f9e7b..0f751cf 100644
--- a/src/util.coffee
+++ b/src/util.coffee
@@ -1,3 +1,5 @@
+import { detect as detectBrowser } from 'detect-browser'
+
# Maimum upload size (in bytes)
MAX_UPLOAD_SIZE = 10 * 1024 * 1024 # 10 MB
@@ -34,18 +36,28 @@ idToPath = (id) ->
# Determine if we show something inline or not
shouldShowInline = (mime) ->
- mime.startsWith('text/') or
+ isText(mime) or
mime.startsWith('image/') or
mime.startsWith('audio/') or
- mime.startsWith('video/') or
+ mime.startsWith('video/')
+
+isText = (mime) ->
+ mime.startsWith('text/') or
mime == 'application/json' or
mime == 'application/javascript'
+# Determine if we consider the user a browser or not
+isBrowser = (req) ->
+ b = detectBrowser req.headers.get 'user-agent'
+ (not b) or (b.name != 'searchbot')
+
export {
getFileName,
validateLength,
MAX_UPLOAD_SIZE,
randomID,
idToPath,
- shouldShowInline
+ shouldShowInline,
+ isBrowser,
+ isText
}
\ No newline at end of file
diff --git a/src/web/codeViewer.coffee b/src/web/codeViewer.coffee
new file mode 100644
index 0000000..7a30275
--- /dev/null
+++ b/src/web/codeViewer.coffee
@@ -0,0 +1,54 @@
+import React from "react"
+import { Redirect } from "react-router-dom"
+import hljs from "highlight.js"
+
+MAX_HIGHLIGHT_LENGTH = 10 * 1024 # 10 KiB
+
+class CodeViewer extends React.Component
+ constructor: (props) ->
+ super props
+ @state =
+ code: "Loading..."
+ switchToHome: false
+ highlight: true
+
+ componentDidMount: ->
+ resp = await fetch "/paste/#{@props.match.params.id}?original"
+ resp = await resp.text()
+ if resp.length < MAX_HIGHLIGHT_LENGTH
+ resp = hljs.highlightAuto(resp).value
+ else
+ @setState
+ highlight: false
+
+ @setState
+ code: resp
+
+ render: ->
+ if @state.switchToHome
+ return
{@state.code}+ } +