Skip to content

Commit

Permalink
Merge pull request #229 from land-code/add-console
Browse files Browse the repository at this point in the history
Add console functionality to the application
  • Loading branch information
midudev authored Jan 17, 2024
2 parents 07fe0b9 + 32ed8ae commit 2e61af4
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 3 deletions.
28 changes: 28 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@
</svg>
</button>

<button class="console-button" aria-label="Show console" data-action="show-console-bar">
<span role="tooltip" class="button-title">Console</span>
<svg viewBox="0 0 24 24" fill="none" >
<path
style="stroke:currentColor;stroke-width:1.4652;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="m 11.932537,19.933734 9.0385,0.01374" />
<path
style="stroke:currentColor;stroke-width:1.703;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 3.5593127,3.9843517 12.442341,11.762526 3.8244778,19.938449" />
</svg>
</button>

<button class="bar-button" aria-label="Download user code" data-action="download-user-code"
data-is-simple-click-action="true">
<span role="tooltip" class="button-title">Download</span>
Expand Down Expand Up @@ -153,6 +165,22 @@
</div>
</div>

<div id="console" hidden class="bar-content console">
<div class="console-content">
<div class="console-item">
<header class="console-header">
<strong>
<span class="console-type">JavaScript:</span>
Console
</strong>
Shows the result of the code execution. Supports log, warn, info and error methods.
</header>

<ul class="console-list"></ul>
</div>
</div>
</div>

<form id="settings" hidden class="bar-content settings">
<div class="settings-content">
<div class="settings-item">
Expand Down
4 changes: 4 additions & 0 deletions src/aside.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const NON_SIMPLE_CLICK_ACTIONS = {
[BUTTON_ACTIONS.showSettingsBar]: () => {
showAsideBar('#settings')
$('.scroll-buttons-container').setAttribute('hidden', '')
},
[BUTTON_ACTIONS.showConsoleBar]: () => {
showAsideBar('#console')
$('.scroll-buttons-container').setAttribute('hidden', '')
}
}

Expand Down
41 changes: 41 additions & 0 deletions src/console-script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export const generateConsoleScript = () => {
return `<script>
const customConsole = (w) => {
const pushToConsole = (payload, type) => {
w.parent.postMessage({
console: {
payload: JSON.stringify(payload),
type: type
}
}, "*")
}
pushToConsole("clear", "system")
w.onerror = (message, url, line, column) => {
pushToConsole({line, column, message}, "error")
}
const console = {
log: function(...args){
pushToConsole(args, "log:log")
},
error: function(...args){
pushToConsole(args, "log:error")
},
warn: function(...args){
pushToConsole(args, "log:warn")
},
info: function(...args){
pushToConsole(args, "log:info")
}
}
window.console = { ...window.console, ...console }
}
if (window.parent){
customConsole(window)
}
</script>`
}
54 changes: 54 additions & 0 deletions src/console.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { CONSOLE_ICONS } from './constants/console-icons'
import { $ } from './utils/dom'

const $iframe = $('iframe')
const $consoleList = $('#console .console-list')

const clearConsole = () => {
$consoleList.innerHTML = ''
}

const isPrimitive = (item) => {
return ['string', 'number', 'boolean', 'symbol', 'bigint'].includes(typeof item) || item === null || item === undefined
}

const createListItem = (content, type) => {
const $li = document.createElement('li')
$li.classList.add(`log-${type.split(':')[1]}`)

$li.innerHTML = CONSOLE_ICONS[type]

const $span = document.createElement('span')
$span.textContent = content
$li.appendChild($span)

return $li
}

const handlers = {
system: (payload) => {
if (payload === 'clear') {
clearConsole()
}
},
error: (payload) => {
const { line, column, message } = payload
const errorItem = createListItem(`${line}:${column} ${message}`, 'error')
errorItem.classList.add('error')
$consoleList.appendChild(errorItem)
},
default: (payload, type) => {
const content = payload.find(isPrimitive) ? payload.join(' ') : payload.map(item => JSON.stringify(item)).join(' ')
const listItem = createListItem(content, type)
$consoleList.appendChild(listItem)
}
}

window.addEventListener('message', (ev) => {
if (ev.source !== $iframe.contentWindow) return
const { type, payload: rawPayload } = ev.data.console
const payload = JSON.parse(rawPayload)

const handler = handlers[type] || handlers.default
handler(payload, type)
})
3 changes: 2 additions & 1 deletion src/constants/button-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export const BUTTON_ACTIONS = {
copyToClipboard: 'copy-to-clipboard',
closeAsideBar: 'close-aside-bar',
showSkypackBar: 'show-skypack-bar',
showSettingsBar: 'show-settings-bar'
showSettingsBar: 'show-settings-bar',
showConsoleBar: 'show-console-bar'
}
76 changes: 76 additions & 0 deletions src/constants/console-icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
export const CONSOLE_ICONS = {
'log:info': `<svg
viewBox="0 0 24 24"
width="16px"
height="16px"
fill="currentColor"
>
<path
style="stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="M 12.557556,20.215488 12.567844,8.0868482" />
<circle
style="fill-opacity:1;stroke:none;stroke-width:1.469;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
cx="12.44614"
cy="3"
r="1.3" />
</svg>`,
'log:error': `<svg
viewBox="0 0 24 24"
fill="currentColor"
width="16px"
height="16px"
stroke="currentColor"
>
<path
style="stroke-width:2.92477;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="M 3.5414066,20.488601 20.616638,3.4133672" />
<path
style="stroke-width:2.92477;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="M 3.5414077,3.4133702 20.616637,20.488598" />
</svg>`,
'log:warn': `<svg
viewBox="0 0 24 24"
fill="currentColor"
stroke="currentColor"
width="16px"
height="16px"
>
<path
style="fill:none;stroke-width:2.14945;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 1.7951514,22.204492 11.807144,1.6087039 22.032806,22.391161 Z" />
<g
transform="translate(0,0.10168155)">
<path
style="stroke-width:2.00514;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 11.968757,7.7809794 11.859197,16.92329" />
<circle
style="fill-opacity:1;stroke:none;stroke-width:13.8929;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
cy="19.387251"
cx="11.913978"
r="1.0575" />
</g>
</svg>`,
'log:log': `<svg
viewBox="0 0 24 24"
fill="currentColor"
stroke="currentColor"
width="16px"
height="16px"
>
<defs
id="defs1" />
<path
style="fill:none;stroke-width:3.90829;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 19.665382,4.7766397 6.7456885,17.063774"
id="path2" />
<path
style="fill:none;stroke-width:3.90801;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 8.3397549,15.536597 -2.3679433,2.22659"
id="path2-1" />
<path
style="fill-opacity:1;stroke:none;stroke-width:3.70014;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 3.1965895,17.679952 2.4341197,21.570486 5.9483739,20.463801"
id="path3" />
</svg>`,
error: null
}
67 changes: 67 additions & 0 deletions src/css/console.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.console {
& .console-header {
background: var(--aside-bar-background);
position: sticky;
top: 0;
z-index: 1;
padding-top: 1em;
}

& .console-type {
padding-bottom: 8px;
opacity: 0.6;
}

& .console-item {
color: #fff;
display: flex;
flex-direction: column;
width: 100%;
padding: 0 1em 1em;
}

& .console-item strong {
display: block;
overflow: hidden;
text-overflow: ellipsis;
}

& .console-list {
list-style: none;
padding: 0;
display: grid;
gap: 0.5em;

& li {
display: flex;
align-items: center;
gap: 1em;
word-break: break-all;
padding: 0 0.5em;
}

& .error {
background: rgb(235, 189, 189);
border: 2px solid rgb(204, 0, 0);
color: black;
}
& .error::before {
content: '❗';
margin-right: 4px;
width: 1em;
}

& .log-log {
color: rgb(205, 238, 181);
}
& .log-info {
color: rgb(181, 181, 238);
}
& .log-error {
color: rgb(227, 189, 189);
}
& .log-warn {
color: rgb(247, 231, 161);
}
}
}
1 change: 1 addition & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import './skypack.js'
import './settings.js'
import './scroll.js'
import './drag-file.js'
import './console.js'

import { BUTTON_ACTIONS } from './constants/button-actions.js'

Expand Down
1 change: 1 addition & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@import url('./css/skypack.css');
@import url('./css/settings.css');
@import url('./css/drag-drop-area.css');
@import url('./css/console.css');

.scroll-buttons-container {
display: none;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/WindowPreviewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function updatePreview ({ html, css, js }) {
URL.revokeObjectURL(previewUrl)
}

const htmlForPreview = createHtml({ html, css, js })
const htmlForPreview = createHtml({ html, css, js }, true)

const blob = new window.Blob([htmlForPreview], { type: 'text/html' })

Expand Down
6 changes: 5 additions & 1 deletion src/utils/createHtml.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// @ts-check

import { generateConsoleScript } from '../console-script'

/**
* Create an index.html content from provided data
* @param {object} params - The parameters
* @param {string} params.css - CSS
* @param {string} params.html - HTML content
* @param {string} params.js - JavaScript
* @param {boolean} isEditor - Whether the code is being run in the editor or preview
* @returns {string}
*/
export const createHtml = ({ css, html, js }) => {
export const createHtml = ({ css, html, js }, isEditor = false) => {
return `<!DOCTYPE html>
<html lang="en">
<head>
Expand All @@ -17,6 +20,7 @@ export const createHtml = ({ css, html, js }) => {
<style id="preview-style">
${css}
</style>
${isEditor ? generateConsoleScript() : ''}
</head>
<body>
${html}
Expand Down

1 comment on commit 2e61af4

@vercel
Copy link

@vercel vercel bot commented on 2e61af4 Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.