Syntax highlighting [Dactyl v0.13 req], generalized get started

This commit is contained in:
mDuo13
2020-09-02 18:22:58 -07:00
parent 3e56f4021e
commit 0beb372a6f
14 changed files with 32127 additions and 161 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,15 @@
var toggle_cs = function(eo) { function toggle_cs(eo) {
//eo = $("#"+id); const wrapper = $(eo.target).parent();
var wrapper = $(eo.target).parent(); const code_el = wrapper.find("code");
var code_el = wrapper.find("code");
code_el.toggleClass('expanded'); code_el.toggleClass('expanded');
var placeholders = wrapper.find(".code-placeholder"); const placeholders = wrapper.find(".code-placeholder");
if (placeholders.length) { if (placeholders.length) {
placeholders.remove(); placeholders.remove();
} else { } else {
code_el.after("<div class='code-placeholder' style='width:" code_el.after("<div class='code-placeholder' style='width:"
+ code_el.width() + code_el.outerWidth()
+ "px; height:" + "px; height:"
+ code_el.height() + code_el.outerHeight()
+ "px;'>&nbsp;</div>"); + "px;'>&nbsp;</div>");
} }
current_button_text = wrapper.find(".code_toggler").val(); current_button_text = wrapper.find(".code_toggler").val();
@@ -40,7 +39,7 @@ function make_code_expandable() {
if (has_scrollbars(this)) { if (has_scrollbars(this)) {
jqThis.dblclick(toggle_cs); jqThis.dblclick(toggle_cs);
jqThis.attr('title', 'Double-click to expand/collapse'); jqThis.attr('title', 'Double-click to expand/collapse');
var newbtn = $("<input type='button' class='code_toggler' value='Expand' />"); var newbtn = $("<input type='button' class='code_toggler btn btn-outline-secondary' value='Expand' />");
newbtn.appendTo(jqThis.parents(".code_sample")); newbtn.appendTo(jqThis.parents(".code_sample"));
} }
}); });

78
assets/js/js-editor.js Normal file
View File

@@ -0,0 +1,78 @@
// Interactive JavaScript editor code
let js_interactives = {};
$(document).ready(()=> {
$(".js_interactive").each((i, el) => {
const wrapper = $(el);
const interactive_id = wrapper.attr("id");
const code_blocks = wrapper.find("pre code");
const code_ex0 = code_blocks.eq(0); // First code block is the default
const og_text = code_ex0.text().trim();
const cm = CodeMirror(wrapper.find(".editor").get(0), {
mode: 'javascript',
json: false,
smartIndent: false,
gutters: ["CodeMirror-lint-markers"],
lint: CodeMirror.lint.javascript
});
cm.setValue(og_text);
code_ex0.parent().hide();
const cm_resp = CodeMirror(wrapper.find(".response").get(0), {
mode: 'javascript',
json: false,
readOnly: true,
gutters: ["CodeMirror-lint-markers"]
});
wrapper.find(".reset-button").click((evt) => {
cm.setValue(og_text);
});
wrapper.find(".run-button").click((evt) => {
cm_resp.setValue("");
const oldconsole = console;
console = {
log: (...args) => {
oldconsole.log(...args);
cm_resp.setValue(args.map(x => JSON.stringify(x, null, 2)).join(" "));
},
warn: (...args) => {
oldconsole.warn(...args);
cm_resp.setValue(args.map(x => JSON.stringify(x, null, 2)).join(" "));
},
error: (...args) => {
oldconsole.error(...args);
cm_resp.setValue(args.map((x) => {
if (x instanceof Error) return x.toString();
return JSON.stringify(x, null, 2);
}).join(" "));
}
}
try {
Function(cm.getValue())();
} catch(error) {
console.error(error);
}
});
js_interactives[interactive_id] = {}
code_blocks.slice(1).each((i, el) => {
// Turn each additional code block into a function that fills in the
// editor with the provided text example.
// Example: js_interactives.some_unique_id.ex_1()
const code_ex = $(el);
const ex_text = code_ex.text().trim();
js_interactives[interactive_id]["ex_"+(i+1)] = function() {
//
cm.setValue(ex_text);
$("html").animate({scrollTop: wrapper.offset().top}, 500);
}
code_ex.parent().hide();
});
})
});

64
assets/vendor/cm-javascript-lint.js vendored Normal file
View File

@@ -0,0 +1,64 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// declare global: JSHINT
function validator(text, options) {
if (!window.JSHINT) {
if (window.console) {
window.console.error("Error: window.JSHINT not defined, CodeMirror JavaScript linting cannot run.");
}
return [];
}
if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation
options.indent = 1; // JSHint default value is 4
options.esversion = 8; // suppress warnings for using modern JS features
JSHINT(text, options, options.globals);
var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result);
return result;
}
CodeMirror.registerHelper("lint", "javascript", validator);
function parseErrors(errors, output) {
for ( var i = 0; i < errors.length; i++) {
var error = errors[i];
if (error) {
if (error.line < 0) {
if (window.console) {
window.console.warn("Cannot display JSHint error (invalid line " + error.line + ")", error);
}
continue;
}
var start = error.character - 1, end = start + 1;
if (error.evidence) {
var index = error.evidence.substring(start).search(/.\b/);
if (index > -1) {
end += index;
}
}
// Convert to format expected by validation service
var hint = {
message: error.reason,
severity: error.code ? (error.code.startsWith('W') ? "warning" : "error") : "error",
from: CodeMirror.Pos(error.line - 1, start),
to: CodeMirror.Pos(error.line - 1, end)
};
output.push(hint);
}
}
}
});

31321
assets/vendor/jshint.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -25,8 +25,10 @@ The following code gets the latest [ledger version](ledgers.html) and a list of
**Tip:** If you can, open your browser's Developer Tools by pressing **F12**. The "Console" tab provides a native JavaScript console and can give insight into what code is running on any webpage. **Tip:** If you can, open your browser's Developer Tools by pressing **F12**. The "Console" tab provides a native JavaScript console and can give insight into what code is running on any webpage.
<div id="step2">
<pre><code id="step2code"> <!-- JS_EDITOR_START step2 -->
```js
const mainnet = new ripple.RippleAPI({ const mainnet = new ripple.RippleAPI({
server: 'wss://s1.ripple.com' server: 'wss://s1.ripple.com'
}); });
@@ -40,66 +42,70 @@ const mainnet = new ripple.RippleAPI({
console.log(response); console.log(response);
})(mainnet); })(mainnet);
</code></pre> ```
<p>
<button type="button" id="step2button" class="btn btn-primary">Run</button> ```js
<button type="reset" id="step2reset" class="btn btn-secondary-outline">Reset</button> const mainnet = new ripple.RippleAPI({
</p> server: 'wss://s.altnet.rippletest.net/'
<h3>Output</h3>
<div id="step2resp"></div>
<link rel="stylesheet" type="text/css" href="assets/vendor/codemirror.css" />
<script src="assets/vendor/codemirror-js-json-lint.min.js"></script>
<script type="application/javascript">
const code_ex = $("#step2code");
const code_text = code_ex.text().trim();
code_ex.text("");
const cm = CodeMirror(code_ex.get(0), {
mode: 'javascript',
json: false,
smartIndent: false,
}); });
cm.setValue(code_text);
const cm_resp = CodeMirror($("#step2resp").get(0), { (async function(api) {
mode: 'javascript', await api.connect();
json: false,
readOnly: true let response = await api.getLedger({
includeTransactions: true
}); });
let ret; console.log(response);
$("#step2button").click((evt) => {
const oldconsole = console; })(mainnet);
console = { ```
log: (...args) => {
oldconsole.log(...args); ```js
args.forEach(arg => cm_resp.setValue(JSON.stringify(arg, null, 2))) const mainnet = new ripple.RippleAPI({
} server: 'wss://s1.ripple.com'
}
Function(cm.getValue())();
}); });
$("#step2reset").click((evt) => {
cm.setValue(code_text); (async function(api) {
await api.connect();
let response = await api.getLedger({
includeTransactions: true
}); });
function fill_ex_1() { let tx_id = response.transactionHashes[0];
cm.setValue("const mainnet = new ripple.RippleAPI({\n server: 'wss://s.altnet.rippletest.net/'\n});\n\n(async function(api) {\n await api.connect();\n\n let response = await api.getLedger({\n includeTransactions: true\n });\n console.log(response);\n\n})(mainnet);"); let response2 = await api.getTransaction(tx_id);
$("html").animate({scrollTop: $("#step2").offset().top}, 500); console.log(response2);
}
function fill_ex_2() { })(mainnet);
cm.setValue("const mainnet = new ripple.RippleAPI({\n server: 'wss://s1.ripple.com'\n});\n\n(async function(api) {\n await api.connect();\n\n let response = await api.getLedger({\n includeTransactions: true\n });\n let tx_id = response.transactionHashes[0];\n let response2 = await api.getTransaction(tx_id);\n console.log(response2);\n\n})(mainnet);"); ```
$("html").animate({scrollTop: $("#step2").offset().top}, 500);
} ```js
function fill_ex_3() { const mainnet = new ripple.RippleAPI({
cm.setValue("const mainnet = new ripple.RippleAPI({\n server: 'wss://s1.ripple.com'\n});\n\n(async function(api) {\n await api.connect();\n\n let response = await api.getLedger({\n includeTransactions: true\n });\n console.log('Total XRP: '+api.dropsToXrp(response.totalDrops));\n\n})(mainnet);"); server: 'wss://s1.ripple.com'
$("html").animate({scrollTop: $("#step2").offset().top}, 500); });
}
</script> (async function(api) {
</div> await api.connect();
let response = await api.getLedger({
includeTransactions: true
});
console.log('Total XRP: '+api.dropsToXrp(response.totalDrops));
})(mainnet);
```
<!-- JS_EDITOR_END -->
## 3. Next Steps ## 3. Next Steps
Try editing the code from step 2 to do something different: Try editing the code from step 2 to do something different:
- Connect to the [Testnet](parallel-networks.html) public server at `wss://s.altnet.rippletest.net/` instead. [Answer >](javascript:fill_ex_1()) - Connect to the [Testnet](parallel-networks.html) public server at `wss://s.altnet.rippletest.net/` instead. [Answer >](javascript:js_interactives.step2.ex_1())
- Look up the details of a transaction using the [`getTransaction()` method](rippleapi-reference.html#gettransaction). For the `id`, use one of the `transactionHashes` from the `getLedger()` response! [Answer >](javascript:fill_ex_2()) - Look up the details of a transaction using the [`getTransaction()` method](rippleapi-reference.html#gettransaction). For the `id`, use one of the `transactionHashes` from the `getLedger()` response! [Answer >](javascript:js_interactives.step2.ex_2())
- Convert the `totalDrops` from the response to decimal XRP. [Answer >](javascript:fill_ex_3()) - Convert the `totalDrops` from the response to decimal XRP. [Answer >](javascript:js_interactives.step2.ex_3())
## Further Reading ## Further Reading

View File

@@ -1459,8 +1459,11 @@ pages:
funnel: Build funnel: Build
doc_type: Tutorials doc_type: Tutorials
category: Get Started category: Get Started
template: template-landing-children.html # template: template-landing-children.html
template: template-doc.html #TEMP
blurb: Get up and running with some of the resources you'll use to work with the XRP Ledger. blurb: Get up and running with some of the resources you'll use to work with the XRP Ledger.
filters:
- js_editor
targets: targets:
- en - en

View File

@@ -1,107 +1,544 @@
/* Code Tabs ---------------------------------------------------------------- */ $code-bg: $gray-900;
$code-padding: 2rem;
.multicode { // Code Tabs -------------------------------------------------------------------
color: $black;
}
.multicode a.current {
background-color: $gray-200;
color: $black;
}
.multicode a,
a.current {
color: $black;
}
.multicode li {
border-color: $gray-300;
}
.code_sample pre code {
background-color: $gray-200;
}
.multicode a:hover {
color: $black;
border-bottom: 1px solid $black;
padding-bottom: 7px;
}
pre { pre {
overflow: visible; color: $white;
background-color: $code-bg;
word-wrap: normal; word-wrap: normal;
} padding: $code-padding;
pre code { border-radius: 4px;
code {
white-space: pre; white-space: pre;
color: $white;
background-color: $code-bg;
} }
.code_sample pre { }
.multicode {
padding: 0;
z-index: 1;
position: relative;
pre {
background: none; background: none;
border: none; border: none;
border-radius: 0; border-radius: 0;
} padding: 0;
.code_sample pre code { clear: both;
code {
overflow: auto; overflow: auto;
max-height: 24em; max-height: 24em;
border-radius: 4px; border-radius: 0 4px 4px 4px;
display: block; display: block;
padding: 24px; padding: $code-padding;
}
.code_sample pre code.expanded { &.expanded {
overflow: visible; overflow: visible;
max-height: none; max-height: none;
position: absolute; position: absolute;
min-width: 100%; // don't shrink horizontally when expanded
}
} }
.code_sample .code_toggler {
position: absolute;
bottom: 0;
right: 0;
} }
.multicode { ul { // code tabs
margin: 12px 0px 0px 0px;
padding: 0 0 0 0;
z-index: 1;
padding-left: 10px;
position: relative;
}
.multicode ul {
margin: 0 !important; margin: 0 !important;
padding: 0; padding: 0;
}
.multicode pre { li {
padding-top: 0;
clear: both;
}
.multicode li {
display: block; display: block;
float: left; float: left;
list-style-type: none; list-style-type: none;
margin-right: 0px; margin-right: 0px;
margin-left: 0px; margin-left: 0px;
border-style: none solid; border: 0;
border-width: 0.5px;
} }
.multicode ul > li:before {
background: none;
border: none;
} }
.multicode a,
a.current { a { // clickable part of the tabs
padding-right: 32px;
padding-left: 32px;
padding-bottom: 10px;
padding-top: 10px;
margin: 0px;
text-decoration: none; text-decoration: none;
color: $white;
background-color: transparent;
padding: .75rem 2rem;
margin: 0;
border-radius: 4px 4px 0 0;
&.current {
background-color: $code-bg;
} }
.multicode a.current:hover { &:hover {
border-bottom: none; text-decoration: none;
padding-bottom: 10px; background-color: $gray-900;
color: $primary;
} }
.multicode li:first-child {
border-left: none;
} }
.multicode li:last-child {
.code_toggler { // expand/collapse button
position: absolute;
bottom: 0;
right: 0;
}
}
// Syntax highlighting via Codehilite ------------------------------------------
.codehilite {
background: $code-bg;
color: $white;
.c, // comment
.ch, // comment, hashbang
.cm, // comment, multiline
.cp, // comment, preproc
.cpf, // comment, preproc file
.c1, // comment, single
.cs // comment, special
{
color: $gray-500;
}
.err { // error
}
.esc { // escape
}
.g, // generic
.gd, // generic, deleted
.ge, // generic, emphasis
.gr, // generic, error
.gh, // generic, heading
.gi, // generic, inserted
.go, // generic, output
.gp, // generic, prompt
.gs, // generic, strong
.gu, // generic, underline / subheading
.gt // generic, traceback
{
}
.k, // keyword
.kc, // keyword, constant
.kd, // keyword, declaration
.kn, // keyword, namespace
.kp, // keyword, pseudo
.kr, // keyword, reserved
.kt // keyword, type
{
color: $orange-500;
}
.l, // literal
.ld // literal, date
{
}
.m, // literal, number
.mb, // number, bin
.mh, // number, hex
.mi, // number, integer
.mo, // number, oct
.il // number, integer, long
{
color: $blue-500;
}
.n, // name
.na, // name, attribute
.nb, // name, builtin
.nc, // name, class
.nd, // name, decorator
.ne, // name, exception
.nf, // name, function
.ni, // name, entity
.nl, // name, label
.nn, // name, namespace
.nt, // name, tag
.nv, // name, variable
.nx, // name, other
.bp, // name, builtin, pseudo
.fm, // name, function, magic
.py // name, property
{
color: $white;
}
.o, // operator
.ow // operator, word
{
}
.p { // punctuation
color: $gray-200;
}
.s, // literal, string
.s1, // string, single
.s2, // string, double
.sa, // string, affix
.sb, // string, backtick
.sc, // string, char
.dl, // string, delimiter
.sd, // string, docstring
.se, // string, escape
.sh, // string, heredoc
.si, // string, interpol
.sr, // string, regex
.ss, // string, symbol
.sx, // string, other
{
color: $green-700;
}
.vc, // variable, class
.vg, // variable, global
.vi, // variable, instance
.vm // variable, magic
{
}
.w { // whitespace
}
.x { // "other"
}
}
.multicode .codehilite {
background: transparent;
}
// CodeMirror (editable code blocks) -------------------------------------------
.CodeMirror {
font-family: $font-family-monospace;
height: 300px;
background-color: $code-bg;
margin: 16px 0;
border-radius: 4px;
}
.CodeMirror-scroll {
overflow: auto;
}
.CodeMirror-lines {
padding: 2rem 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 2rem 0 1rem; /* Horizontal padding of content w/ room for 1rem gutter */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: $black; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
background-color: $code-bg;
white-space: nowrap;
}
/* CURSOR */
.CodeMirror div.CodeMirror-cursor {
border-left: 1px solid $white;
z-index: 3;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid $gray-500;
}
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
width: auto;
border: 0;
background: $gray-500;
z-index: 1;
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
.cm-tab { display: inline-block; }
/* DEFAULT THEME - modified for XRPL.org */
.cm-s-default .cm-keyword {color: $orange-500;}
.cm-s-default .cm-atom {color: $orange-500;}
.cm-s-default .cm-number {color: $blue-500;}
.cm-s-default .cm-def {color: $blue-500;}
.cm-s-default .cm-variable {color: $white;}
.cm-s-default .cm-variable-2 {color: $white;}
.cm-s-default .cm-variable-3 {color: $white;}
.cm-s-default .cm-property {color: $white;}
.cm-s-default .cm-operator {color: $white;}
.cm-s-default .cm-comment {color: $gray-500;}
.cm-s-default .cm-string {color: $green-700;}
.cm-s-default .cm-string-2 {color: $green-700;}
.cm-s-default .cm-meta {color: $gray-500;}
.cm-s-default .cm-qualifier {color: $gray-500;}
.cm-s-default .cm-builtin {color: $green-700;}
.cm-s-default .cm-bracket {color: $white;}
.cm-s-default .cm-tag {color: $white;}
.cm-s-default .cm-attribute {color: $white;}
.cm-s-default .cm-header {color: $blue-500;}
.cm-s-default .cm-quote {color: $green-700;}
.cm-s-default .cm-hr {color: $gray-500;}
.cm-s-default .cm-link {color: $blue-200;}
.cm-negative {color: $white;}
.cm-positive {color: $white;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-s-default .cm-error {color: $danger;}
.cm-invalidchar {color: $danger;}
div.CodeMirror span.CodeMirror-matchingbracket {color: $blue-purple-500;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: $warning;}
.CodeMirror-activeline-background {background: $gray-800;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
line-height: 1;
position: relative;
overflow: hidden;
background: $code-bg;
color: $white;
}
.CodeMirror-scroll {
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px; padding-right: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actuall scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
padding-bottom: 30px;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding-bottom: 30px;
margin-bottom: -32px;
display: inline-block;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-lines {
cursor: text;
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-code pre {
border-right: 30px solid transparent;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
.CodeMirror-wrap .CodeMirror-code pre {
border-right: none; border-right: none;
width: auto;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor {
position: absolute;
visibility: hidden;
border-right: none;
width: 0;
}
.CodeMirror-focused div.CodeMirror-cursor {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursor {
visibility: hidden;
}
}
/* ADDON: lint.css ---------------------------------------------------------- */
/* The lint marker gutter */
.CodeMirror-lint-markers {
width: 16px;
}
.CodeMirror-lint-tooltip {
background-color: #ffd;
border: 1px solid black;
border-radius: 4px 4px 4px 4px;
color: black;
font-family: monospace;
font-size: 10pt;
overflow: hidden;
padding: 2px 5px;
position: fixed;
white-space: pre;
white-space: pre-wrap;
z-index: 100;
max-width: 600px;
opacity: 0;
transition: opacity .4s;
-moz-transition: opacity .4s;
-webkit-transition: opacity .4s;
-o-transition: opacity .4s;
-ms-transition: opacity .4s;
}
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
background-position: left bottom;
background-repeat: repeat-x;
}
.CodeMirror-lint-mark-error {
background-image:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")
;
}
.CodeMirror-lint-mark-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning {
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
display: inline-block;
height: 16px;
width: 16px;
vertical-align: middle;
position: relative;
}
.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning {
padding-left: 18px;
background-position: top left;
background-repeat: no-repeat;
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: right bottom;
width: 100%; height: 100%;
} }

View File

@@ -10,7 +10,7 @@ $border-radius-sm: 0;
$dropdown-border-width: 1px; $dropdown-border-width: 1px;
// @import "_font-face.scss"; // @import "_font-face.scss";
$font-family-monospace: 'Work Sans', monospace; $font-family-monospace: 'Space Mono', monospace;
$font-family-sans-serif: -apple-system, system-ui, 'Roboto', sans-serif; $font-family-sans-serif: -apple-system, system-ui, 'Roboto', sans-serif;
// Bootstrap v4 // Bootstrap v4
@@ -25,9 +25,9 @@ $font-family-sans-serif: -apple-system, system-ui, 'Roboto', sans-serif;
@import "_tables.scss"; @import "_tables.scss";
@import "_use-cases.scss"; @import "_use-cases.scss";
@import "_github-edit.scss"; @import "_github-edit.scss";
@import "_code-tabs.scss";
@import "_top-nav.scss"; @import "_top-nav.scss";
@import "_content.scss"; @import "_content.scss";
@import "_code-tabs.scss";
@import "_diagrams.scss"; @import "_diagrams.scss";
@import "_external-links.scss"; @import "_external-links.scss";
@import "_footer.scss"; @import "_footer.scss";

55
tool/filter_js_editor.py Normal file
View File

@@ -0,0 +1,55 @@
# JS Editor Filter
# Author: Rome Reginelli
# Copyright: Ripple Labs, 2020
#
# Requires: CodeMirror (JS & CSS), js-editor.js
#
# Converts a code block into an editable JavaScript interpreter, with
# "Run" and "Reset" buttons, and an output box that copies console.log().
# Code blocks beyond the first get turned into functions that replace the
# code block's contents and scroll to it.
# Syntax:
#
# <!-- JS_EDITOR_START some_unique_id_here -->
#
# ```js
# const foo = "bar"; // This is the default value
# ```
#
# ```js
# const baz = "Non-default value"
# ```
#
# <!-- JS_EDITOR_END -->
#
import re
import logging
START_REGEX = re.compile(r"<!--\s*JS_EDITOR_START\s*(\w+)\s*-->")
END_REGEX = re.compile(r"<!--\s*JS_EDITOR_END\s*-->")
START_REPL = """<div class="js_interactive" id="\\1">
<div class="editor"></div>"""
END_REPL = """
<p>
<button type="button" class="btn btn-primary run-button">Run</button>
<button type="reset" class="btn btn-secondary-outline reset-button">Reset</button>
</p>
<h3>Output</h3>
<div class="response"></div>
</div>"""
def filter_html(html, mode="html", **kwargs):
"""
Replace the editor with a div after markdown is parsed
"""
if mode == "md": # shouldn't even come up, but just in case... don't do it
return html
html = re.sub(START_REGEX, START_REPL, html)
html = re.sub(END_REGEX, END_REPL, html)
return html

View File

@@ -1,9 +1,6 @@
{% extends "template-base.html" %} {% extends "template-base.html" %}
{% block head %} {% block head %}
<!-- syntax highlighting -->
<link rel="stylesheet" href="assets/vendor/docco.min.css" />
<script src="assets/vendor/highlight.min.js"></script>
<!-- expandable code samples --> <!-- expandable code samples -->
<script src="assets/js/expandcode.js"></script> <script src="assets/js/expandcode.js"></script>
@@ -12,11 +9,17 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$(".multicode").minitabs(); $(".multicode").minitabs();
hljs.initHighlighting();
make_code_expandable(); make_code_expandable();
}); });
</script> </script>
{% if "js_editor" in currentpage.filters %}
<script src="assets/vendor/jshint.js"></script>
<script src="assets/vendor/codemirror-js-json-lint.min.js"></script>
<script src="assets/vendor/cm-javascript-lint.js"></script>
<script src="assets/js/js-editor.js"></script>
{% endif %}
{% endblock %} {% endblock %}

View File

@@ -55,7 +55,7 @@
var DOC_BASE = '{{ currentpage.doc_page }}'; var DOC_BASE = '{{ currentpage.doc_page }}';
</script> </script>
<link rel='stylesheet' type='text/css' href='assets/css/api-tools.css'/> <link rel='stylesheet' type='text/css' href='assets/css/api-tools.css'/>
<link rel='stylesheet' type='text/css' href='assets/vendor/codemirror.css'/> <!-- <link rel='stylesheet' type='text/css' href='assets/vendor/codemirror.css'/> -->
<script type='text/javascript' src='assets/js/es5-shim.js'></script> <script type='text/javascript' src='assets/js/es5-shim.js'></script>
<script type='text/javascript' src='assets/vendor/codemirror-js-json-lint.min.js'></script> <script type='text/javascript' src='assets/vendor/codemirror-js-json-lint.min.js'></script>
<script type='text/javascript' src='assets/vendor/cm-javascript.min.js'></script> <script type='text/javascript' src='assets/vendor/cm-javascript.min.js'></script>

View File

@@ -176,7 +176,7 @@
</div><!--/.modal--> </div><!--/.modal-->
<script type="text/javascript" src="assets/vendor/jsonlint.js"></script> <script type="text/javascript" src="assets/vendor/jsonlint.js"></script>
<link rel="stylesheet" type="text/css" href="assets/vendor/codemirror.css"/> <!-- <link rel="stylesheet" type="text/css" href="assets/vendor/codemirror.css"/> -->
<script type="text/javascript" src="assets/vendor/codemirror-js-json-lint.min.js"></script> <script type="text/javascript" src="assets/vendor/codemirror-js-json-lint.min.js"></script>
<script type="text/javascript" src="assets/js/apitool-websocket.js"></script> <script type="text/javascript" src="assets/js/apitool-websocket.js"></script>
<script type="text/javascript" src="assets/js/apitool-methods-ws.js"></script> <script type="text/javascript" src="assets/js/apitool-methods-ws.js"></script>