Skip to content

Instantly share code, notes, and snippets.

@newhouseb
Last active October 19, 2018 20:24
Show Gist options
  • Save newhouseb/3b2180811b4453232fe2c2b08e0b012a to your computer and use it in GitHub Desktop.
Save newhouseb/3b2180811b4453232fe2c2b08e0b012a to your computer and use it in GitHub Desktop.
Github Menus #pocketbook
<div class="metadata" style="display: none;"></div>
<div data-lang="md" data-visibility="output" data-autorun="false" class="block hide-source" data-source-visibility="hidden">
<pre class="source hljs coffeescript" contenteditable="true"><span class="hljs-comment"># Github UI</span>
</pre>
<div class="result"><h1 id="githubui">Github UI</h1></div>
</div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source hljs javascript" contenteditable="true"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createOrUpdateWithId</span>(<span class="hljs-params">id, tag</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-built_in">document</span>.getElementById(id) || (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">var</span> div = <span class="hljs-built_in">document</span>.createElement(tag || <span class="hljs-string">'div'</span>);
div.id = id;
<span class="hljs-keyword">return</span> div;
})();
}
<span class="hljs-keyword">var</span> githubMenu = createOrUpdateWithId(<span class="hljs-string">'githubmenu'</span>);
githubMenu.innerHTML = <span class="hljs-string">''</span>;
githubMenu.style.position = <span class="hljs-string">'fixed'</span>;
githubMenu.style.top = <span class="hljs-string">'0px'</span>;
githubMenu.style.right = <span class="hljs-string">'0px'</span>;
githubMenu.className = <span class="hljs-string">'githubmenu'</span>;
<span class="hljs-built_in">document</span>.body.appendChild(githubMenu);<div><br></div><div>var createRow = document.createElement('div');</div><div>createRow.className = 'githubcreaterow';</div><div><br></div><div>var createInput = document.createElement('input');</div><div>createInput.className = 'githubcreateinput';</div><div>createInput.placeholder = 'New Pocketbook Title'</div><div>createRow.appendChild(createInput);
<br></div><div><span class="hljs-keyword">var</span> createButton = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
createButton.className = <span class="hljs-string">'githubcreatebutton'</span>;
createButton.innerHTML = <span class="hljs-string">'+'</span>;
createRow.appendChild(createButton);</div><div><br></div><div>githubMenu.appendChild(createRow);</div><div>
<span class="hljs-keyword">var</span> style = createOrUpdateWithId(<span class="hljs-string">'githubstyles'</span>, <span class="hljs-string">'style'</span>);
<span class="hljs-keyword">while</span>(style.firstChild) { style.removeChild(style.firstChild); }
style.appendChild(<span class="hljs-built_in">document</span>.createTextNode(<span class="hljs-string">`
.githubmenu {
position: relative;
}</span></div><div><span class="hljs-string"> .githubmenu:hover {</span></div><div><span class="hljs-string"> border-left: 1px solid #cecece;</span></div><div><span class="hljs-string"> border-bottom: 1px solid #cecece;</span></div><div><span class="hljs-string"> }</span></div><div><span class="hljs-string"> .githubmenu:hover .githubbanner {</span></div><div><span class="hljs-string"> border-bottom: 1px solid #cecece;</span></div><div><span class="hljs-string"> }</span></div><div><font color="#880000"><span style="caret-color: rgb(136, 0, 0);"> .githubmenu &gt; div {</span></font></div><div><font color="#880000"><span style="caret-color: rgb(136, 0, 0);"> display: none;</span></font></div><div><font color="#880000"><span style="caret-color: rgb(136, 0, 0);"> }<br></span></font><div><span class="hljs-string"> .githubbanner {</span></div><div><span class="hljs-string"> font-family: helvetica, arial, sans-serif;</span></div><div><span class="hljs-string"> padding: 20px;</span></div><div><span style="color: rgb(136, 0, 0);"> display: block !important;</span></div><div><span class="hljs-string"> text-align: right;</span></div><div><span class="hljs-string"> padding-right: 50px;</span></div><div><span class="hljs-string"> color: #ccc;</span></div><div><span style="color: rgb(136, 0, 0);"> }</span></div><div><span class="hljs-string"> .githubmenu:hover &gt; div {</span></div><div><span class="hljs-string"> display: block !important;</span></div><div><span class="hljs-string"> }</span></div><div><span class="hljs-string"> .githubcreaterow {</span></div><div><span class="hljs-string"> border-bottom: 1px solid #cecece;</span></div><div><span class="hljs-string"> padding: 5px;</span></div><div><span class="hljs-string"> position: relative;</span></div><div><span class="hljs-string"> height: 32px;</span></div><div><span class="hljs-string"> }</span></div><div><span class="hljs-string"> .githubcreateinput {</span></div><div><span class="hljs-string"> border: 0px;</span></div><div><span class="hljs-string"> border-bottom: 1px solid #cecece;</span></div><div><span class="hljs-string"> width: 220px;</span></div><div><span class="hljs-string"> font-size: 20px;</span></div><div><span class="hljs-string"> margin-top: 2px;</span></div><div><span class="hljs-string"> margin-left: 5px;</span></div><div><span class="hljs-string"> outline: none;</span></div><div><span class="hljs-string"> }
.githubgist {
cursor: pointer;
padding: 10px;
min-width: 250px;
border-bottom: 1px solid #cecece;
position: relative;
background-color: white;
}
.githubgist:hover {
background-color: #f3f3f3 !important;
}
.githubgist:last-child {
border-bottom: 0px;
}
.githubtitle {
font-size: 20px;
font-weight: bold;
font-family: helvetica, arial, sans-serif;
}
.githubtag {
background-color: #cecece;
color: white;
border-radius: 5px;
padding: 5px;
display: inline-block;
font-size: 12px;
font-family: helvetica, arial, sans-serif;
}
.githubopenelsewhere, .githubcreatebutton, .githublogoutbutton {
border: 1px solid #cecece;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 5px;
color: #cecece;
position: absolute;
top: 10px;
right: 10px;</span></div><div><span class="hljs-string"> cursor: pointer;</span></div><div><span class="hljs-string"> }</span></div><div><span class="hljs-string"> .githubopenelsewhere, .githublogoutbutton {
visibility: hidden;
}</span></div><div><span class="hljs-string"> .githubopenelsewhere:hover, .githubcreatebutton:hover, .githublogoutbutton:hover {
background-color: #999;
color: white;
}
.githubgist:hover .githubopenelsewhere {
visibility: visible;
}</span></div><div><span class="hljs-string"> .githubbanner:hover .githublogoutbutton {</span></div><div><span class="hljs-string"> visibility: visible;</span></div><div><span class="hljs-string"> top: 20px;</span></div><div><span class="hljs-string"> }
`</span>));
<span class="hljs-built_in">document</span>.head.appendChild(style);
<span class="hljs-keyword">var</span> xhttp = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhttp.open(<span class="hljs-string">'GET'</span>, <span class="hljs-string">'https://api.github.com/user?access_token='</span> + <span class="hljs-built_in">window</span>.localStorage.githubkey)
xhttp.addEventListener(<span class="hljs-string">'load'</span>, (e) =&gt; {
<span class="hljs-keyword">if</span> (xhttp.readyState == <span class="hljs-number">4</span> &amp;&amp; xhttp.status == <span class="hljs-number">200</span>) {
<span class="hljs-keyword">var</span> result = <span class="hljs-built_in">JSON</span>.parse(xhttp.response); &nbsp;
<span class="hljs-keyword">var</span> banner = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);<div> banner.className = 'githubbanner';
<span class="hljs-keyword">var</span> name = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'span'</span>);
name.innerHTML = <span class="hljs-string">'Connected to &lt;b'+'&gt;'</span> + result.login + <span class="hljs-string">'&lt;' + '/b&gt; &amp;' + 'nbsp;'</span>;
banner.appendChild(name);</div><div><br></div><div> <span class="hljs-keyword">var</span> icon = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'img'</span>);
icon.src = <span class="hljs-string">'https://github.com/favicon.ico'</span>;
icon.style.verticalAlign = <span class="hljs-string">'text-bottom'</span>;
icon.style.width = <span class="hljs-string">'20px'</span>;
icon.style.height = <span class="hljs-string">'20px'</span>;
banner.appendChild(icon);</div><div><br></div><div> var logoutButton = document.createElement('div');
logoutButton.className = 'githublogoutbutton';
logoutButton.innerHTML = 'x';
banner.appendChild(logoutButton);
githubMenu.insertBefore(banner, githubMenu.firstChild);
}
});
xhttp.send();
(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">var</span> xhttp = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhttp.open(<span class="hljs-string">'GET'</span>, <span class="hljs-string">'https://api.github.com/gists?access_token='</span> + <span class="hljs-built_in">window</span>.localStorage.githubkey)
xhttp.addEventListener(<span class="hljs-string">'load'</span>, (e) =&gt; {
<span class="hljs-keyword">if</span> (xhttp.readyState == <span class="hljs-number">4</span> &amp;&amp; xhttp.status == <span class="hljs-number">200</span>) {
<span class="hljs-keyword">var</span> result = <span class="hljs-built_in">JSON</span>.parse(xhttp.response);
<span class="hljs-keyword">var</span> pocketbooks = [];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; result.length; i++) {
&nbsp; <span class="hljs-keyword">if</span> (result[i].description.indexOf(<span class="hljs-string">'#pocketbook'</span>) != <span class="hljs-number">-1</span>) {
pocketbooks.push(result[i]);
}
}
<span class="hljs-keyword">var</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
<span class="hljs-keyword">var</span> formatPocketbook = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">info</span>) </span>{
<span class="hljs-keyword">var</span> gist = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
gist.className = <span class="hljs-string">'githubgist'</span>;
gist.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-built_in">window</span>.location = <span class="hljs-string">'https://gist-'</span> + info.id + <span class="hljs-string">'.pocketbook.software'</span>;
});
<span class="hljs-keyword">var</span> titleDescription = info.description.replace(<span class="hljs-regexp">/#[_a-z0-9A-Z]+/g</span>, <span class="hljs-string">''</span>).trim();
<span class="hljs-keyword">var</span> tags = info.description.match(<span class="hljs-regexp">/#[_a-z0-9A-Z]+/g</span>);
<span class="hljs-keyword">var</span> title = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
title.innerHTML = titleDescription;
title.className = <span class="hljs-string">'githubtitle'</span>;
gist.appendChild(title);
<span class="hljs-keyword">var</span> tagList = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j &lt; tags.length; j++) {
<span class="hljs-keyword">var</span> tag = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'span'</span>);
tag.innerHTML = tags[j];
tag.className = <span class="hljs-string">'githubtag'</span>;
tagList.appendChild(tag);
}
gist.appendChild(tagList);
<span class="hljs-keyword">var</span> openElsewhere = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
openElsewhere.className = <span class="hljs-string">'githubopenelsewhere'</span>;
openElsewhere.innerHTML = <span class="hljs-string">'↗'</span>;
openElsewhere.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
<span class="hljs-built_in">window</span>.open(<span class="hljs-string">'https://gist-'</span> + info.id + <span class="hljs-string">'.pocketbook.software'</span>, <span class="hljs-string">'_blank'</span>);
<b>e.stopPropagation();</b>
});
gist.appendChild(openElsewhere);
<span class="hljs-keyword">return</span> gist;
}
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; pocketbooks.length; i++) {
div.appendChild(formatPocketbook(pocketbooks[i]));
}
githubMenu.appendChild(div);
}
});
xhttp.send();
})();
<span class="hljs-string">'ok!'</span>
</div></div></div></pre><div class="result"><pre>ok!</pre></div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs cs" contenteditable="true">Now, <span class="hljs-keyword">let</span><span class="hljs-string">'s get a little fancy and add a new language. We'</span>ll <span class="hljs-keyword">add</span> my LISP <span class="hljs-keyword">using</span> a dependency block. A dependency block includes other scripts, <span class="hljs-function">one per each <span class="hljs-title">line</span> (<span class="hljs-params"><span class="hljs-keyword">in</span> parallel, but we only have one here</span>):</span></pre><div class="result"><p>Now, let's get a little fancy and add a new language. We'll add my LISP using a dependency block. A dependency block includes other scripts, one per each line (in parallel, but we only have one here):</p></div></div><div data-lang="deps" data-source-visibility="visible" data-result-visibility="hidden" data-autorun="true" class="block hide-result"><pre class="source hljs cpp" contenteditable="true">https:<span class="hljs-comment">//pocketbook.software/lib/blip-071718.js</span></pre><div class="result" style="display: none;">[object Event]</div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs sql" contenteditable="true">Now let's <span class="hljs-keyword">use</span> the aforementioned <span class="hljs-keyword">self</span>-<span class="hljs-keyword">modification</span> <span class="hljs-keyword">to</span> wire up the <span class="hljs-string">`evaluate`</span> <span class="hljs-keyword">function</span> <span class="hljs-keyword">as</span> a separate runtime!</pre><div class="result"><p>Now let's use the aforementioned self-modification to wire up the <code>evaluate</code> function as a separate runtime!</p></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="hidden" data-autorun="true" class="block hide-result"><pre class="source hljs php" contenteditable="true">PocketBook.Main.Languages[<span class="hljs-string">'blip'</span>] = {
name: <span class="hljs-string">"Blip"</span>,
<span class="hljs-keyword">eval</span>: evaluate <span class="hljs-comment">// This comes from the above script</span>
} </pre><div class="result" style="display: none;">[object Object]</div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs sql" contenteditable="true">Once this is run, we can <span class="hljs-keyword">use</span> a <span class="hljs-keyword">new</span> <span class="hljs-keyword">language</span> (selected <span class="hljs-keyword">at</span> the bottom <span class="hljs-keyword">of</span> the menu <span class="hljs-keyword">on</span> the <span class="hljs-keyword">left</span> <span class="hljs-keyword">to</span> run blocks <span class="hljs-keyword">of</span> code <span class="hljs-keyword">with</span>!)</pre><div class="result"><p>Once this is run, we can use a new language (selected at the bottom of the menu on the left to run blocks of code with!)</p></div></div><div data-lang="blip" data-source-visibility="visible" data-result-visibility="visible" data-autorun="false" class="block"><pre class="source hljs bash" contenteditable="true">(<span class="hljs-built_in">let</span> (x 2)
(+ (* x x) (+ (* 3 x) 4))) </pre><div class="result">14</div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs markdown" contenteditable="true">---
<span class="hljs-code"> </span>
<span class="hljs-code"> # FAQ</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> **Where are things saved?**</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> By default, things are saved to local storage in your browser. If you'd like something more permanent, you can save to a Github Gist (see the menu in the top left corner). You'll need to make a personal access token to do so.</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> **Why not fork Jupyter/Iodide/ObservableHQ?**</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> A few different reasons:</span>
<span class="hljs-code"> - ObservableHQ isn't open source, as far as I can tell.</span>
<span class="hljs-code"> - I didn't to run servers (a la Jupyter): browsers are powerful these days! [https://pocketbook.software](https://pocketbook.software) is literally just an HTML page in an AWS S3 bucket (behind CloudFront for HTTPS).</span>
<span class="hljs-code"> - I wanted something tiny that made minimal assumptions about the front-end framework or transpiler de jour so that it had staying power.</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> **Can I add X feature?**</span>
<span class="hljs-code"> </span>
<span class="hljs-code"> My first suggestion would be to try to add it inline: all of the PocketBook state is available for you to modify and the code should be pretty readable. If that doesn't work, send me a pull request! If it's good, I'll merge it.</span>
<span class="hljs-code"> </span>
If it's helpful, I wrote a little function that should dump out the latest layout of the global <span class="hljs-code">`PocketBook`</span> object. <span class="hljs-code">`PocketBook.Main`</span> refers to the main instance.</pre><div class="result"><hr>
<h1 id="faq">FAQ</h1>
<p><strong>Where are things saved?</strong></p>
<p>By default, things are saved to local storage in your browser. If you'd like something more permanent, you can save to a Github Gist (see the menu in the top left corner). You'll need to make a personal access token to do so.</p>
<p><strong>Why not fork Jupyter/Iodide/ObservableHQ?</strong></p>
<p>A few different reasons:</p>
<ul>
<li>ObservableHQ isn't open source, as far as I can tell.</li>
<li>I didn't to run servers (a la Jupyter): browsers are powerful these days! <a href="https://pocketbook.software">https://pocketbook.software</a> is literally just an HTML page in an AWS S3 bucket (behind CloudFront for HTTPS).</li>
<li>I wanted something tiny that made minimal assumptions about the front-end framework or transpiler de jour so that it had staying power.</li>
</ul>
<p><strong>Can I add X feature?</strong></p>
<p>My first suggestion would be to try to add it inline: all of the PocketBook state is available for you to modify and the code should be pretty readable. If that doesn't work, send me a pull request! If it's good, I'll merge it.</p>
<p>If it's helpful, I wrote a little function that should dump out the latest layout of the global <code>PocketBook</code> object. <code>PocketBook.Main</code> refers to the main instance.</p></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="false" class="block"><pre class="source hljs css" contenteditable="true"><span class="hljs-selector-tag">PocketBook</span><span class="hljs-selector-class">.Help</span>()</pre><div class="result"><pre>Storage [Object]
LocalStorageBackingStore [Class]
GistBackingStore [Class]
StorageManager [Class]
UI [Object]
StatelessBlockAction [Class]
ToggleBlockAction [Class]
BlockController [Class]
StatelessGlobalAction [Class]
TopBarController [Class]
HotKeyManager [Class]
Main [PocketBook]
Version [Array]
Content [HTMLDivElement]
Languages [Object]
BlockController [BlockController]
Parent [PocketBook]
Actions [Array]
LastBlock [HTMLDivElement]
TopBarController [TopBarController]
Parent [PocketBook]
Actions [Array]
StorageManager [StorageManager]
Parent [PocketBook]
Source [GistBackingStore]
Id [String]
HotKeyManager [HotKeyManager]
Parent [PocketBook]
Help [Function]
</pre></div></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment