Developer-Dashboard
view release on metacpan or search on metacpan
lib/Developer/Dashboard/Web/App.pm view on Meta::CPAN
my $source = $raw_source;
$source =~ s/&/&/g;
$source =~ s/</</g;
$source =~ s/>/>/g;
my $page_id = $page->as_hash->{id} || '';
my $is_saved = ( $page->{meta}{source_kind} || '' ) ne 'transient' && $page_id ne '';
my $page_url = $is_saved ? $self->_saved_page_url($page_id) : '';
my $urls = {
edit => $is_saved ? $page_url . '/edit' : $self->{pages}->editable_url($page),
render => $is_saved ? $page_url : $self->{pages}->render_url($page),
source => $is_saved ? $page_url . '/edit' : $self->{pages}->editable_url($page),
};
my $form_action = $is_saved ? $page_url . '/edit' : '/';
my $title = $page->as_hash->{title};
$title =~ s/&/&/g;
$title =~ s/</</g;
$title =~ s/>/>/g;
my $html = <<'HTML';
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>__TITLE__</title>
<style>
body { margin: 0; font-family: Georgia, serif; background: #f5efe2; color: #1f2a2e; }
main { max-width: 980px; margin: 32px auto; background: #fffef9; border: 1px solid #ddd3c2; padding: 24px; }
.editor-stack {
position: relative;
min-height: 520px;
border: 1px solid #2a2f36;
background: #1f2328;
overflow: hidden;
}
.editor-overlay,
.instruction-editor {
display: block;
width: 100%;
min-height: 520px;
box-sizing: border-box;
margin: 0;
padding: 12px;
font-family: Menlo, Consolas, "Courier New", monospace;
font-size: 14px;
line-height: 21px;
white-space: pre;
word-break: normal;
overflow-wrap: normal;
overflow: auto;
tab-size: 4;
letter-spacing: 0;
}
.editor-overlay-viewport {
position: absolute;
inset: 0;
overflow: hidden;
pointer-events: none;
background: transparent;
}
.editor-overlay {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
color: #e6edf3;
background: transparent;
unicode-bidi: plaintext;
direction: ltr;
will-change: transform;
}
.instruction-editor {
position: relative;
z-index: 1;
height: 520px;
color: transparent;
border: 0;
resize: vertical;
background: transparent;
caret-color: #f8f8f2;
outline: none;
-webkit-text-fill-color: transparent;
unicode-bidi: plaintext;
direction: ltr;
overflow: auto;
scrollbar-gutter: stable both-edges;
}
.instruction-editor::selection {
background: rgba(121, 192, 255, 0.35);
-webkit-text-fill-color: transparent;
}
.tok-directive { color: #ffd866; font-weight: normal; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.tok-separator { color: #5c6370; }
.tok-html { color: #78dce8; }
.tok-tag { color: #ff7ab2; }
.tok-attr { color: #ffcf6a; }
.tok-value { color: #a9dc76; }
.tok-css { color: #78dce8; }
.tok-js { color: #ab9df2; }
.tok-code { color: #a9dc76; }
.tok-perl-keyword { color: #ff7ab2; }
.tok-perl-var { color: #78dce8; }
.tok-string { color: #ffd866; }
.tok-comment { color: #727b84; }
.tok-note { color: #ff6188; }
a { color: #0b7a75; margin-right: 18px; text-decoration: none; }
</style>
</head>
<body>
<main>
__TOP_CHROME__
<form method="post" action="__FORM_ACTION__" id="instruction-form">
<div class="editor-stack">
<div class="editor-overlay-viewport" aria-hidden="true"><pre class="editor-overlay" id="instruction-highlight">__INITIAL_HIGHLIGHT__</pre></div>
<textarea class="instruction-editor" id="instruction-editor" name="instruction" wrap="off" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off">__SOURCE__</textarea>
</div>
</form>
</main>
<script>
const ddForm = document.getElementById('instruction-form');
const ddEditor = document.getElementById('instruction-editor');
const ddHighlight = document.getElementById('instruction-highlight');
function ddEscapeHtml(text) {
return String(text)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
}
function ddStoreToken(tokens, html) {
tokens.push(html);
return '\u001eHL' + (tokens.length - 1) + '\u001e';
}
function ddRestoreTokens(text, tokens) {
if (!Array.isArray(tokens) || !tokens.length) return text;
return String(text).replace(/\u001eHL(\d+)\u001e/g, function(_, index) {
return Object.prototype.hasOwnProperty.call(tokens, index) ? tokens[index] : '';
});
}
function ddHighlightInstruction(text) {
const state = { section: '', htmlMode: '' };
return String(text).split('\n').map((line) => ddHighlightLine(line, state)).join('\n');
}
function ddHighlightLine(line, state) {
if (line === ':--------------------------------------------------------------------------------:') {
return '<span class="tok-separator">' + ddEscapeHtml(line) + '</span>';
}
const match = line.match(/^([A-Za-z][A-Za-z0-9.]*:)(\s*)(.*)$/);
if (match) {
state.section = match[1].slice(0, -1).toUpperCase();
state.htmlMode = '';
( run in 0.841 second using v1.01-cache-2.11-cpan-39bf76dae61 )