<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://unpkg.com/manuel@0.62.0/dist/style.css">
<title>JS Bin</title>
</head>
<body>
<script src="https://unpkg.com/manuel@0.63.0/dist/manuel.js"></script>
<script src="https://unpkg.com/mithril@1.1.3/mithril.min.js"></script>
<script src="https://unpkg.com/mithril-stream@1.1.0/stream.js"></script>
<script src="https://unpkg.com/ramda@0.24.1/dist/ramda.min.js"></script>
<script>
const Maybe = {
Just(x){
return { of: Maybe.Just, x}
}
,Nothing(){
return { of: Maybe.Nothing }
}
,map(f){
return function(Ma){
return Ma.of == Maybe.Just
? Maybe.Just( f(Ma.x) )
: Maybe.Nothing()
}
}
}
function afterSilence(ms, s) {
const r = m.stream()
var timeoutId
var last
s.map(function(){
last = s()
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
r(last);
}, ms);
})
return r
}
const indexBy = f => xs =>
xs.reduce(function(p, n){
p[f(n)] = n
return p
}, {})
const MithrilStreamAutocomplete = manuel({
hyperscript: m
,get: o => o()
,set: (o, x) => o(x)
})
function GithubUserSearch(){
const items = m.stream([])
const loginIndex = items.map(indexBy( o => o.login))
const model = {
list: items.map(
xs => xs.map(o => o.login)
)
,input: m.stream('JAForb')
,chosen: m.stream()
,open: m.stream(true)
,highlighted: m.stream('')
}
const request =
afterSilence(1000, model.input).map(function(x){
return x != model.chosen()
&& x != null
&& x.length > 2
? Maybe.Just({
method: 'GET'
, url: 'https://api.github.com/search/users?q=' + x
})
: Maybe.Nothing()
})
// side effects
request
.map(
Maybe.map(function(req){
m.request(req)
.then( res => res.items )
.then( xs => items(xs) )
})
)
m.stream.merge(
Object.keys(model)
.map( k => model[k] )
.concat([ loginIndex ])
)
.map( () => m.redraw() )
const view = () =>
m('label', 'Search Github Users'
,MithrilStreamAutocomplete( model, {
filter: () => true
,sort(a, b){
var A = loginIndex()[a]
var B = loginIndex()[b]
return a.score - b.score
}
,renderItem(x, { mark, clickItem }){
var o = loginIndex()[x]
return m('li'
,{ className:
o.login == model.highlighted()
? 'highlight'
: ''
, onmousedown: () => {
clickItem(x)
}
}
, m('span'
,{ style: { display: 'block', height: '32px' }}
,m('img'
,{ src: o.avatar_url
, width: '32px'
, height: '32px'
, style: { position: 'absolute' }
}
)
,m('span'
,{ style:
{ position: 'absolute'
, display: 'block'
, height: '32px'
, transform: [
['32px', '25%']
,['8px', '0px']
]
.map(
(xy) => 'translate('+xy+')'
)
.join(' ')
}
}
, mark(x)
)
)
)
}
})
)
return { view }
}
const App = {
view(){
return m(GithubUserSearch)
}
}
m.mount(document.body, App)
</script>
</body>
</html>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |