mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-28 19:55:53 +03:00
finished transitioning to query schema
This commit is contained in:
parent
109b5fd962
commit
91c1492d0e
@ -16,7 +16,6 @@
|
||||
::
|
||||
++ json-front
|
||||
|= a=json ^- json
|
||||
=< ?~(. [%b |] .) :: XX overloaded nulls
|
||||
=- (fall `(unit json)`- ~)
|
||||
%+ biff ((ar some):jo a)
|
||||
%+ find-in-tree (ot c/(ar some) gn/so ga/(om so) ~):jo
|
||||
|
@ -23,6 +23,7 @@ which is normalized and type-checked(request types are `%t` text, `%r` html-deri
|
||||
- `[%kids query]`, the only recursive value, which executes for all subpaths
|
||||
XX descent is only currently supported to a single level as a performance optimization
|
||||
- `[%name %t]`, the node name
|
||||
- `[%path %t]`, the current path
|
||||
- `[%snip %r]`, a snippet, extracted via `react-snip-json`
|
||||
- `[%head %r]`, the first header, extracted via `react-head-json`
|
||||
- `[%body %r]`, the `react-json` body
|
||||
|
@ -229,7 +229,7 @@ li:before {
|
||||
transition: opacity 1s ease-in-out;
|
||||
z-index: 4;
|
||||
}
|
||||
#nav > div > div {
|
||||
#nav .links > div {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ li:before
|
||||
transition opacity 1s ease-in-out
|
||||
z-index 4
|
||||
|
||||
#nav > div > div
|
||||
#nav .links > div
|
||||
display inline-block
|
||||
vertical-align top
|
||||
|
||||
@ -362,4 +362,4 @@ div.post
|
||||
.error
|
||||
color rgba(249,23,51,1)
|
||||
|
||||
@import 'mobile'
|
||||
@import 'mobile'
|
||||
|
@ -21,35 +21,14 @@ module.exports =
|
||||
path:path
|
||||
kids:kids
|
||||
|
||||
getPath: (path,query) ->
|
||||
sendQuery: (path,query) ->
|
||||
return unless query?
|
||||
if path.slice(-1) is "/" then path = path.slice(0,-1)
|
||||
|
||||
if typeof query is 'string'
|
||||
query={ # XX unify
|
||||
body: {
|
||||
body:'r'
|
||||
kids:
|
||||
name:'t'
|
||||
}
|
||||
kids: {
|
||||
kids:
|
||||
name:'t'
|
||||
body:'r'
|
||||
}
|
||||
snip: {
|
||||
kids:
|
||||
name:'t'
|
||||
snip:'r'
|
||||
head:'r'
|
||||
meta:'j'
|
||||
}
|
||||
}[query]
|
||||
|
||||
|
||||
TreePersistence.get path,query,(err,res) =>
|
||||
switch
|
||||
when query.kids?.snip then @loadSnip path,res.kids
|
||||
when query.kids?.body then @loadKids path,res.kids
|
||||
when query.kids?.head then @loadSnip path,res.kids
|
||||
else @loadPath path,res.body,res.kids
|
||||
|
||||
setCurr: (path) ->
|
||||
|
@ -1,5 +1,7 @@
|
||||
clas = require 'classnames'
|
||||
|
||||
BodyComponent = React.createFactory require './BodyComponent.coffee'
|
||||
reactify = React.createFactory require './Reactify.coffee'
|
||||
query = require './Async.coffee'
|
||||
|
||||
TreeStore = require '../stores/TreeStore.coffee'
|
||||
TreeActions = require '../actions/TreeActions.coffee'
|
||||
@ -7,88 +9,61 @@ TreeActions = require '../actions/TreeActions.coffee'
|
||||
recl = React.createClass
|
||||
{div,a} = React.DOM
|
||||
|
||||
module.exports = recl
|
||||
Links = React.createFactory query {
|
||||
path:'t'
|
||||
kids:
|
||||
name:'t'
|
||||
head:'r'
|
||||
meta:'j'
|
||||
}, (recl
|
||||
# {curr:'t',prev:'t,next:'t',onClick:'f'}
|
||||
displayName: "Links"
|
||||
render: -> div {className:'links'}, @props.children, @_render()
|
||||
_render: ->
|
||||
keys = _(@props.kids).keys().sort()
|
||||
style = {marginTop: -24 * (keys.indexOf @props.curr) + "px"}
|
||||
div {id:"sibs",style}, keys.map (key) =>
|
||||
href = window.tree.basepath @props.path+"/"+key
|
||||
data = @props.kids[key]
|
||||
head = data.meta.title if data.meta
|
||||
head ?= @toText data.head
|
||||
head ||= key
|
||||
className = clas active: key is @props.curr
|
||||
(div {className,key}, (a {href,onClick:@props.onClick}, head))
|
||||
|
||||
toText: (elem)-> switch
|
||||
# manx: {fork: ["string", {gn:"string" ga:{dict:"string"} c:{list:"manx"}}]}
|
||||
when !elem? then ""
|
||||
when typeof elem == "string" then elem
|
||||
when elem.gn? then (elem.c ? []).map(@toText).join ""
|
||||
else throw "Bad react-json #{JSON.stringify elem}"
|
||||
), recl
|
||||
displayName: "Links_loading"
|
||||
render: -> div {className:'links'}, @props.children, @_render()
|
||||
_render: -> div {id:"sibs"}, div {className:"active"}, a {}, @props.curr
|
||||
|
||||
module.exports = query {sein:'t',path:'t',name:'t',next:'t',prev:'t'},recl
|
||||
displayName: "Anchor"
|
||||
stateFromStore: ->
|
||||
{
|
||||
path:TreeStore.getCurr()
|
||||
pare:TreeStore.getPare()
|
||||
sibs:TreeStore.getSiblings()
|
||||
snip:TreeStore.getSnip()
|
||||
next:TreeStore.getNext()
|
||||
prev:TreeStore.getPrev()
|
||||
cont:TreeStore.getCont()
|
||||
url:window.location.pathname
|
||||
}
|
||||
getInitialState: -> url: window.location.pathname
|
||||
|
||||
onClick: -> @toggleFocus()
|
||||
onMouseOver: -> @toggleFocus true
|
||||
onMouseOut: -> @toggleFocus false
|
||||
onTouchStart: -> @ts = Number Date.now()
|
||||
onTouchEnd: -> dt = @ts - Number Date.now()
|
||||
|
||||
toggleFocus: (state) ->
|
||||
$(@getDOMNode()).toggleClass 'focus',state
|
||||
|
||||
_click: -> @toggleFocus()
|
||||
|
||||
_mouseOver: -> @toggleFocus true
|
||||
|
||||
_mouseOut: -> @toggleFocus false
|
||||
|
||||
_touchStart: ->
|
||||
@ts = Number Date.now()
|
||||
|
||||
_touchEnd: ->
|
||||
dt = @ts - Number Date.now()
|
||||
|
||||
setPath: (href,hist) ->
|
||||
href_parts = href.split("#")
|
||||
next = href_parts[0]
|
||||
if next.substr(-1) is "/" then next = next.slice(0,-1)
|
||||
href_parts[0] = next
|
||||
if hist isnt false
|
||||
history.pushState {}, "", window.tree.basepath href_parts.join ""
|
||||
if next isnt @state.path
|
||||
React.unmountComponentAtNode $('#cont')[0]
|
||||
TreeActions.setCurr next
|
||||
React.render (BodyComponent {}, ""),$('#cont')[0]
|
||||
|
||||
goTo: (path) ->
|
||||
@toggleFocus false
|
||||
$("html,body").animate {scrollTop:0}
|
||||
@setPath path
|
||||
|
||||
checkURL: ->
|
||||
if @state.url isnt window.location.pathname
|
||||
@setPath (window.tree.fragpath window.location.pathname),false
|
||||
|
||||
setTitle: ->
|
||||
title = $('#cont h1').first().text()
|
||||
if title.length is 0
|
||||
path = @state.path.split("/")
|
||||
title = path[path.length-1]
|
||||
|
||||
document.title = "#{title} - #{@state.path}"
|
||||
|
||||
checkUp: ->
|
||||
up = @state.pare ? "/"
|
||||
if up.slice(-1) is "/" then up = up.slice 0,-1
|
||||
|
||||
unless @state.cont[up]? then TreeActions.getPath up, "body"
|
||||
|
||||
unless TreeStore.gotSnip(up) then TreeActions.getPath up, "snip"
|
||||
|
||||
componentDidUpdate: ->
|
||||
@setTitle()
|
||||
@checkUp()
|
||||
toggleFocus: (state) -> $(@getDOMNode()).toggleClass 'focus',state
|
||||
|
||||
componentDidUpdate: -> @setTitle()
|
||||
componentWillUnmount: -> clearInterval @interval; $('body').off 'click', 'a'
|
||||
componentDidMount: ->
|
||||
TreeStore.addChangeListener @_onChangeStore
|
||||
|
||||
@setTitle()
|
||||
@checkUp()
|
||||
|
||||
@interval = setInterval @checkURL,100
|
||||
|
||||
$('body').on 'keyup', (e) =>
|
||||
switch e.keyCode
|
||||
when 37 then @goTo @state.prev # left
|
||||
when 39 then @goTo @state.next # right
|
||||
when 37 then @goTo @props.prev # left
|
||||
when 39 then @goTo @props.next # right
|
||||
|
||||
$('body').on 'click', 'a', (e) =>
|
||||
href = $(e.target).closest('a').attr('href')
|
||||
@ -97,60 +72,50 @@ module.exports = recl
|
||||
e.stopPropagation()
|
||||
@goTo window.tree.fragpath href
|
||||
|
||||
componentWillUnmount: ->
|
||||
clearInterval @interval
|
||||
$('body').off 'click', 'a'
|
||||
setTitle: ->
|
||||
title = $('#cont h1').first().text() || @props.name
|
||||
document.title = "#{title} - #{@props.path}"
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
setPath: (href,hist) ->
|
||||
href_parts = href.split("#")
|
||||
next = href_parts[0]
|
||||
if next.substr(-1) is "/" then next = next.slice(0,-1)
|
||||
href_parts[0] = next
|
||||
if hist isnt false
|
||||
history.pushState {}, "", window.tree.basepath href_parts.join ""
|
||||
if next isnt @props.path
|
||||
React.unmountComponentAtNode $('#cont')[0]
|
||||
TreeActions.setCurr next
|
||||
React.render (BodyComponent {}, ""),$('#cont')[0]
|
||||
|
||||
_onChangeStore: -> @setState @stateFromStore()
|
||||
goTo: (path) ->
|
||||
@toggleFocus false
|
||||
$("html,body").animate {scrollTop:0}
|
||||
@setPath path
|
||||
|
||||
checkURL: ->
|
||||
if @state.url isnt window.location.pathname
|
||||
@setPath (window.tree.fragpath window.location.pathname),false
|
||||
@setState url: window.location.pathname
|
||||
|
||||
renderArrow: (name, path) ->
|
||||
href = window.tree.basepath path
|
||||
(a {href,key:"arow-#{name}",className:"arow-#{name}"},"")
|
||||
|
||||
toText: (elem)-> $(React.renderToStaticMarkup reactify manx: elem).text()
|
||||
|
||||
renderParts: -> [
|
||||
if @state.pare then _.filter [
|
||||
div {id:"up",key:"up"}, @renderArrow "up", @state.pare
|
||||
if @state.prev or @state.next
|
||||
div {id:"sides",key:"sides"}, _.filter [
|
||||
if @state.prev then @renderArrow "prev", @state.prev
|
||||
if @state.next then @renderArrow "next", @state.next
|
||||
] ]
|
||||
if _.keys(@state.sibs).length > 0
|
||||
[up..., curr] = @state.path.split "/"
|
||||
up = up.join "/"
|
||||
ci=0
|
||||
k=0
|
||||
_sibs = _(@state.sibs).keys().sort().map (i) =>
|
||||
if curr is i
|
||||
className = "active"
|
||||
ci = k
|
||||
className ?= ""
|
||||
k++
|
||||
path = up+"/"+i
|
||||
href = window.tree.basepath path
|
||||
snip = @state.snip[path]
|
||||
head = snip?.meta?.title
|
||||
head ?= @toText snip?.head if snip?.head
|
||||
head ||= i
|
||||
(div {className,key:i}, (a {href,onClick:@_click}, head))
|
||||
style = {marginTop:"#{-24*ci}px"}
|
||||
div {key:"sibs",id:"sibs",style}, _sibs
|
||||
]
|
||||
|
||||
render: ->
|
||||
obj =
|
||||
onMouseOver:@_mouseOver
|
||||
onMouseOut:@_mouseOut
|
||||
onClick:@_click
|
||||
onTouchStart:@_touchStart
|
||||
onTouchEnd:@_touchEnd
|
||||
|
||||
obj = {@onMouseOver,@onMouseOut,@onClick,@onTouchStart,@onTouchEnd}
|
||||
if _.keys(window).indexOf("ontouchstart") isnt -1
|
||||
delete obj.onMouseOver
|
||||
delete obj.onMouseOut
|
||||
|
||||
div obj, _.filter @renderParts()
|
||||
div obj, Links {
|
||||
@onClick
|
||||
curr:@props.name
|
||||
dataPath:@props.sein
|
||||
}, if @props.sein then _.filter [
|
||||
div {id:"up",key:"up"}, @renderArrow "up", @props.sein
|
||||
if @props.prev or @props.next then _.filter [
|
||||
div {id:"sides",key:"sides"},
|
||||
if @props.prev then @renderArrow "prev", @props.prev
|
||||
if @props.next then @renderArrow "next", @props.next
|
||||
] ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
load = React.createFactory require './LoadComponent.coffee'
|
||||
_load = require './LoadComponent.coffee'
|
||||
|
||||
TreeStore = require '../stores/TreeStore.coffee'
|
||||
TreeActions = require '../actions/TreeActions.coffee'
|
||||
@ -6,25 +6,36 @@ TreeActions = require '../actions/TreeActions.coffee'
|
||||
recl = React.createClass
|
||||
{div,span,code} = React.DOM
|
||||
|
||||
module.exports = (queries, Child)-> recl
|
||||
module.exports = (queries, Child, load=_load)-> recl
|
||||
displayName: "Async"
|
||||
stateFromStore: ->
|
||||
path= @props.dataPath ? TreeStore.getCurr()
|
||||
{path,got: TreeStore.fulfill path, queries}
|
||||
|
||||
getInitialState: -> @stateFromStore()
|
||||
_onChangeStore: ->
|
||||
@setState @stateFromStore()
|
||||
|
||||
getPath: -> @props.dataPath ? TreeStore.getCurr()
|
||||
stateFromStore: -> got: TreeStore.fulfill @getPath(), queries
|
||||
|
||||
componentDidMount: ->
|
||||
TreeStore.addChangeListener @_onChangeStore
|
||||
@checkPath()
|
||||
|
||||
|
||||
componentWillUnmount: ->
|
||||
TreeStore.removeChangeListener @_onChangeStore
|
||||
|
||||
componentDidUpdate: (_props,_state) -> @checkPath()
|
||||
|
||||
componentDidUpdate: (_props,_state) ->
|
||||
if _props isnt @props
|
||||
@setState @stateFromStore()
|
||||
@checkPath()
|
||||
|
||||
checkPath: -> TreeActions.sendQuery @getPath(), @filterQueries()
|
||||
|
||||
filterQueries: -> @filterWith @state.got, queries
|
||||
filterWith: (have,_queries)->
|
||||
return _queries unless have?
|
||||
request = {}
|
||||
for k of _queries
|
||||
request[k] = _queries[k] unless have[k]?
|
||||
request[k] = _queries[k] unless have[k] isnt undefined
|
||||
if _queries.kids? and have.kids?
|
||||
if _.isEmpty have.kids
|
||||
request.kids = _queries.kids
|
||||
@ -35,16 +46,10 @@ module.exports = (queries, Child)-> recl
|
||||
if _.isEmpty request.kids
|
||||
delete request.kids
|
||||
request unless _.isEmpty request
|
||||
|
||||
checkPath: -> TreeActions.getPath @state.path, @filterQueries()
|
||||
getInitialState: -> @stateFromStore()
|
||||
_onChangeStore: ->
|
||||
@setState @stateFromStore()
|
||||
|
||||
render: -> div {},
|
||||
#span {}, JSON.stringify @filterQueries()
|
||||
if @filterQueries()?
|
||||
(div {className:"loading"}, (load {}, ""))
|
||||
React.createElement load, @props
|
||||
else React.createElement Child,
|
||||
(_.merge @props, @state.got),
|
||||
@props.children
|
||||
(_.merge {}, @props, @state.got),
|
||||
@props.children
|
||||
|
@ -4,7 +4,7 @@ query = require './Async.coffee'
|
||||
recl = React.createClass
|
||||
{div,a,ul,li,hr} = React.DOM
|
||||
|
||||
module.exports = query {kids: body:'r'},recl
|
||||
module.exports = query {kids: body:'r'}, recl
|
||||
displayName: "Kids"
|
||||
render: -> div {className:"kids"},
|
||||
for v in _.keys(@props.kids).sort()
|
||||
|
@ -28,7 +28,7 @@ module.exports = query {
|
||||
path = @props.path+"/"+item
|
||||
elem = @props.kids[item]
|
||||
href = window.tree.basepath path
|
||||
li {className:@props.dataType ? ""},
|
||||
li {key:item,className:@props.dataType ? ""},
|
||||
a {href,className:(clas preview: @props.dataPreview?)},
|
||||
if not @props.dataPreview? then (h1 {},item)
|
||||
else if @props.dataType is 'post'
|
||||
@ -41,4 +41,4 @@ module.exports = query {
|
||||
gn: 'div'
|
||||
c: [head, (elem.snip.c.slice 0,2)...]
|
||||
else if @props.titlesOnly? then reactify elem.head
|
||||
else [(reactify elem.head), (reactify elem.snip)]
|
||||
else div {}, (reactify elem.head), (reactify elem.snip)
|
||||
|
@ -1,7 +1,7 @@
|
||||
recl = React.createClass
|
||||
{div,input,textarea} = React.DOM
|
||||
|
||||
module.exports = recl
|
||||
module.exports = recl
|
||||
displayName: "Load"
|
||||
getInitialState: -> {anim: 0}
|
||||
|
||||
@ -14,5 +14,5 @@ module.exports = recl
|
||||
if anim > 3 then anim = 0
|
||||
@setState {anim:anim}
|
||||
|
||||
render: ->
|
||||
(div {className:"spin state-#{@state.anim}"}, "")
|
||||
render: -> (div {className:"loading"},
|
||||
(div {className:"spin state-#{@state.anim}"}, ""))
|
||||
|
@ -17,12 +17,12 @@ components =
|
||||
module.exports = recl
|
||||
displayName: "Virtual"
|
||||
render: -> @walk @props.manx
|
||||
walk: (obj,key) -> switch
|
||||
walk: (elem,key) -> switch
|
||||
# manx: {fork: ["string", {gn:"string" ga:{dict:"string"} c:{list:"manx"}}]}
|
||||
when !obj? then (span {className:"loading"}, (load {}, ""))
|
||||
when typeof obj == "string" then obj
|
||||
when obj.gn?
|
||||
React.createElement components[obj.gn] ? obj.gn,
|
||||
$.extend {key}, obj.ga
|
||||
obj.c.map @walk
|
||||
else throw "Bad react-json #{JSON.stringify obj}"
|
||||
when !elem? then (load {}, "")
|
||||
when typeof elem == "string" then elem
|
||||
when elem.gn?
|
||||
React.createElement components[elem.gn] ? elem.gn,
|
||||
$.extend {key}, elem.ga
|
||||
elem.c?.map @walk
|
||||
else throw "Bad react-json #{JSON.stringify elem}"
|
||||
|
@ -63,10 +63,10 @@ module.exports = {
|
||||
return function(err, res) {
|
||||
var ref, ref1;
|
||||
switch (false) {
|
||||
case !((ref = query.kids) != null ? ref.snip : void 0):
|
||||
return _this.loadSnip(path, res.kids);
|
||||
case !((ref1 = query.kids) != null ? ref1.body : void 0):
|
||||
case !((ref = query.kids) != null ? ref.body : void 0):
|
||||
return _this.loadKids(path, res.kids);
|
||||
case !((ref1 = query.kids) != null ? ref1.head : void 0):
|
||||
return _this.loadSnip(path, res.kids);
|
||||
default:
|
||||
return _this.loadPath(path, res.body, res.kids);
|
||||
}
|
||||
@ -84,12 +84,13 @@ module.exports = {
|
||||
|
||||
|
||||
},{"../dispatcher/Dispatcher.coffee":10,"../persistence/TreePersistence.coffee":16}],2:[function(require,module,exports){
|
||||
var BodyComponent, TreeActions, TreeStore, a, div, reactify, recl, ref,
|
||||
slice = [].slice;
|
||||
var BodyComponent, Links, TreeActions, TreeStore, a, clas, div, query, recl, ref;
|
||||
|
||||
clas = require('classnames');
|
||||
|
||||
BodyComponent = React.createFactory(require('./BodyComponent.coffee'));
|
||||
|
||||
reactify = React.createFactory(require('./Reactify.coffee'));
|
||||
query = require('./Async.coffee');
|
||||
|
||||
TreeStore = require('../stores/TreeStore.coffee');
|
||||
|
||||
@ -99,106 +100,122 @@ recl = React.createClass;
|
||||
|
||||
ref = React.DOM, div = ref.div, a = ref.a;
|
||||
|
||||
module.exports = recl({
|
||||
Links = React.createFactory(query({
|
||||
path: 't',
|
||||
kids: {
|
||||
name: 't',
|
||||
head: 'r',
|
||||
meta: 'j'
|
||||
}
|
||||
}, recl({
|
||||
displayName: "Links",
|
||||
render: function() {
|
||||
var keys, style;
|
||||
keys = _(this.props.kids).keys().sort();
|
||||
style = {
|
||||
marginTop: -24 * (keys.indexOf(this.props.curr)) + "px"
|
||||
};
|
||||
return div({
|
||||
id: "sibs",
|
||||
style: style
|
||||
}, keys.map((function(_this) {
|
||||
return function(key) {
|
||||
var className, data, head, href;
|
||||
href = window.tree.basepath(_this.props.path + "/" + key);
|
||||
data = _this.props.kids[key];
|
||||
if (data.meta) {
|
||||
head = data.meta.title;
|
||||
}
|
||||
if (head == null) {
|
||||
head = _this.toText(data.head);
|
||||
}
|
||||
head || (head = key);
|
||||
className = clas({
|
||||
active: key === _this.props.curr
|
||||
});
|
||||
return div({
|
||||
className: className,
|
||||
key: key
|
||||
}, a({
|
||||
href: href,
|
||||
onClick: _this.props.onClick
|
||||
}, head));
|
||||
};
|
||||
})(this)));
|
||||
},
|
||||
toText: function(elem) {
|
||||
var ref1;
|
||||
switch (false) {
|
||||
case !(elem == null):
|
||||
return "";
|
||||
case typeof elem !== "string":
|
||||
return elem;
|
||||
case elem.gn == null:
|
||||
return ((ref1 = elem.c) != null ? ref1 : []).map(this.toText).join("");
|
||||
default:
|
||||
throw "Bad react-json " + (JSON.stringify(elem));
|
||||
}
|
||||
}
|
||||
}), recl({
|
||||
displayName: "Links_loading",
|
||||
render: function() {
|
||||
return div({
|
||||
id: "sibs"
|
||||
}, div({
|
||||
className: "active"
|
||||
}, a({}, this.props.curr)));
|
||||
}
|
||||
})));
|
||||
|
||||
module.exports = query({
|
||||
sein: 't',
|
||||
path: 't',
|
||||
name: 't',
|
||||
next: 't',
|
||||
prev: 't'
|
||||
}, recl({
|
||||
displayName: "Anchor",
|
||||
stateFromStore: function() {
|
||||
getInitialState: function() {
|
||||
return {
|
||||
path: TreeStore.getCurr(),
|
||||
pare: TreeStore.getPare(),
|
||||
sibs: TreeStore.getSiblings(),
|
||||
snip: TreeStore.getSnip(),
|
||||
next: TreeStore.getNext(),
|
||||
prev: TreeStore.getPrev(),
|
||||
cont: TreeStore.getCont(),
|
||||
url: window.location.pathname
|
||||
};
|
||||
},
|
||||
onClick: function() {
|
||||
return this.toggleFocus();
|
||||
},
|
||||
onMouseOver: function() {
|
||||
return this.toggleFocus(true);
|
||||
},
|
||||
onMouseOut: function() {
|
||||
return this.toggleFocus(false);
|
||||
},
|
||||
onTouchStart: function() {
|
||||
return this.ts = Number(Date.now());
|
||||
},
|
||||
onTouchEnd: function() {
|
||||
var dt;
|
||||
return dt = this.ts - Number(Date.now());
|
||||
},
|
||||
toggleFocus: function(state) {
|
||||
return $(this.getDOMNode()).toggleClass('focus', state);
|
||||
},
|
||||
_click: function() {
|
||||
return this.toggleFocus();
|
||||
},
|
||||
_mouseOver: function() {
|
||||
return this.toggleFocus(true);
|
||||
},
|
||||
_mouseOut: function() {
|
||||
return this.toggleFocus(false);
|
||||
},
|
||||
_touchStart: function() {
|
||||
return this.ts = Number(Date.now());
|
||||
},
|
||||
_touchEnd: function() {
|
||||
var dt;
|
||||
return dt = this.ts - Number(Date.now());
|
||||
},
|
||||
setPath: function(href, hist) {
|
||||
var href_parts, next;
|
||||
href_parts = href.split("#");
|
||||
next = href_parts[0];
|
||||
if (next.substr(-1) === "/") {
|
||||
next = next.slice(0, -1);
|
||||
}
|
||||
href_parts[0] = next;
|
||||
if (hist !== false) {
|
||||
history.pushState({}, "", window.tree.basepath(href_parts.join("")));
|
||||
}
|
||||
if (next !== this.state.path) {
|
||||
React.unmountComponentAtNode($('#cont')[0]);
|
||||
TreeActions.setCurr(next);
|
||||
return React.render(BodyComponent({}, ""), $('#cont')[0]);
|
||||
}
|
||||
},
|
||||
goTo: function(path) {
|
||||
this.toggleFocus(false);
|
||||
$("html,body").animate({
|
||||
scrollTop: 0
|
||||
});
|
||||
return this.setPath(path);
|
||||
},
|
||||
checkURL: function() {
|
||||
if (this.state.url !== window.location.pathname) {
|
||||
return this.setPath(window.tree.fragpath(window.location.pathname), false);
|
||||
}
|
||||
},
|
||||
setTitle: function() {
|
||||
var path, title;
|
||||
title = $('#cont h1').first().text();
|
||||
if (title.length === 0) {
|
||||
path = this.state.path.split("/");
|
||||
title = path[path.length - 1];
|
||||
}
|
||||
return document.title = title + " - " + this.state.path;
|
||||
},
|
||||
checkUp: function() {
|
||||
var ref1, up;
|
||||
up = (ref1 = this.state.pare) != null ? ref1 : "/";
|
||||
if (up.slice(-1) === "/") {
|
||||
up = up.slice(0, -1);
|
||||
}
|
||||
if (this.state.cont[up] == null) {
|
||||
TreeActions.getPath(up, "body");
|
||||
}
|
||||
if (!TreeStore.gotSnip(up)) {
|
||||
return TreeActions.getPath(up, "snip");
|
||||
}
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
this.setTitle();
|
||||
return this.checkUp();
|
||||
return this.setTitle();
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
clearInterval(this.interval);
|
||||
return $('body').off('click', 'a');
|
||||
},
|
||||
componentDidMount: function() {
|
||||
TreeStore.addChangeListener(this._onChangeStore);
|
||||
this.setTitle();
|
||||
this.checkUp();
|
||||
this.interval = setInterval(this.checkURL, 100);
|
||||
$('body').on('keyup', (function(_this) {
|
||||
return function(e) {
|
||||
switch (e.keyCode) {
|
||||
case 37:
|
||||
return _this.goTo(_this.state.prev);
|
||||
return _this.goTo(_this.props.prev);
|
||||
case 39:
|
||||
return _this.goTo(_this.state.next);
|
||||
return _this.goTo(_this.props.next);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
@ -214,15 +231,42 @@ module.exports = recl({
|
||||
};
|
||||
})(this));
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
clearInterval(this.interval);
|
||||
return $('body').off('click', 'a');
|
||||
setTitle: function() {
|
||||
var title;
|
||||
title = $('#cont h1').first().text() || this.props.name;
|
||||
return document.title = title + " - " + this.props.path;
|
||||
},
|
||||
getInitialState: function() {
|
||||
return this.stateFromStore();
|
||||
setPath: function(href, hist) {
|
||||
var href_parts, next;
|
||||
href_parts = href.split("#");
|
||||
next = href_parts[0];
|
||||
if (next.substr(-1) === "/") {
|
||||
next = next.slice(0, -1);
|
||||
}
|
||||
href_parts[0] = next;
|
||||
if (hist !== false) {
|
||||
history.pushState({}, "", window.tree.basepath(href_parts.join("")));
|
||||
}
|
||||
if (next !== this.props.path) {
|
||||
React.unmountComponentAtNode($('#cont')[0]);
|
||||
TreeActions.setCurr(next);
|
||||
return React.render(BodyComponent({}, ""), $('#cont')[0]);
|
||||
}
|
||||
},
|
||||
_onChangeStore: function() {
|
||||
return this.setState(this.stateFromStore());
|
||||
goTo: function(path) {
|
||||
this.toggleFocus(false);
|
||||
$("html,body").animate({
|
||||
scrollTop: 0
|
||||
});
|
||||
return this.setPath(path);
|
||||
},
|
||||
checkURL: function() {
|
||||
if (this.state.url !== window.location.pathname) {
|
||||
this.setPath(window.tree.fragpath(window.location.pathname), false);
|
||||
return this.setState({
|
||||
url: window.location.pathname
|
||||
});
|
||||
}
|
||||
},
|
||||
renderArrow: function(name, path) {
|
||||
var href;
|
||||
@ -233,83 +277,46 @@ module.exports = recl({
|
||||
className: "arow-" + name
|
||||
}, "");
|
||||
},
|
||||
toText: function(elem) {
|
||||
return $(React.renderToStaticMarkup(reactify({
|
||||
manx: elem
|
||||
}))).text();
|
||||
},
|
||||
renderParts: function() {
|
||||
var _sibs, ci, curr, j, k, ref1, style, up;
|
||||
return [
|
||||
this.state.pare ? _.filter([
|
||||
div({
|
||||
id: "up",
|
||||
key: "up"
|
||||
}, this.renderArrow("up", this.state.pare)), this.state.prev || this.state.next ? div({
|
||||
id: "sides",
|
||||
key: "sides"
|
||||
}, _.filter([this.state.prev ? this.renderArrow("prev", this.state.prev) : void 0, this.state.next ? this.renderArrow("next", this.state.next) : void 0])) : void 0
|
||||
]) : void 0, _.keys(this.state.sibs).length > 0 ? ((ref1 = this.state.path.split("/"), up = 2 <= ref1.length ? slice.call(ref1, 0, j = ref1.length - 1) : (j = 0, []), curr = ref1[j++], ref1), up = up.join("/"), ci = 0, k = 0, _sibs = _(this.state.sibs).keys().sort().map((function(_this) {
|
||||
return function(i) {
|
||||
var className, head, href, path, ref2, snip;
|
||||
if (curr === i) {
|
||||
className = "active";
|
||||
ci = k;
|
||||
}
|
||||
if (className == null) {
|
||||
className = "";
|
||||
}
|
||||
k++;
|
||||
path = up + "/" + i;
|
||||
href = window.tree.basepath(path);
|
||||
snip = _this.state.snip[path];
|
||||
head = snip != null ? (ref2 = snip.meta) != null ? ref2.title : void 0 : void 0;
|
||||
if (snip != null ? snip.head : void 0) {
|
||||
if (head == null) {
|
||||
head = _this.toText(snip != null ? snip.head : void 0);
|
||||
}
|
||||
}
|
||||
head || (head = i);
|
||||
return div({
|
||||
className: className,
|
||||
key: i
|
||||
}, a({
|
||||
href: href,
|
||||
onClick: _this._click
|
||||
}, head));
|
||||
};
|
||||
})(this)), style = {
|
||||
marginTop: (-24 * ci) + "px"
|
||||
}, div({
|
||||
key: "sibs",
|
||||
id: "sibs",
|
||||
style: style
|
||||
}, _sibs)) : void 0
|
||||
];
|
||||
},
|
||||
render: function() {
|
||||
var obj;
|
||||
obj = {
|
||||
onMouseOver: this._mouseOver,
|
||||
onMouseOut: this._mouseOut,
|
||||
onClick: this._click,
|
||||
onTouchStart: this._touchStart,
|
||||
onTouchEnd: this._touchEnd
|
||||
onMouseOver: this.onMouseOver,
|
||||
onMouseOut: this.onMouseOut,
|
||||
onClick: this.onClick,
|
||||
onTouchStart: this.onTouchStart,
|
||||
onTouchEnd: this.onTouchEnd
|
||||
};
|
||||
if (_.keys(window).indexOf("ontouchstart") !== -1) {
|
||||
delete obj.onMouseOver;
|
||||
delete obj.onMouseOut;
|
||||
}
|
||||
return div(obj, _.filter(this.renderParts()));
|
||||
return div(obj, _.filter([
|
||||
this.props.sein ? _.filter([
|
||||
div({
|
||||
id: "up",
|
||||
key: "up"
|
||||
}, this.renderArrow("up", this.props.sein)), this.props.prev || this.props.next ? _.filter([
|
||||
div({
|
||||
id: "sides",
|
||||
key: "sides"
|
||||
}, this.props.prev ? this.renderArrow("prev", this.props.prev) : void 0, this.props.next ? this.renderArrow("next", this.props.next) : void 0)
|
||||
]) : void 0
|
||||
]) : void 0, Links({
|
||||
onClick: this.onClick,
|
||||
key: "sibs",
|
||||
curr: this.props.name,
|
||||
dataPath: this.props.sein
|
||||
})
|
||||
]));
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
|
||||
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":17,"./BodyComponent.coffee":4,"./Reactify.coffee":9}],3:[function(require,module,exports){
|
||||
var TreeActions, TreeStore, code, div, load, recl, ref, span;
|
||||
},{"../actions/TreeActions.coffee":1,"../stores/TreeStore.coffee":17,"./Async.coffee":3,"./BodyComponent.coffee":4,"classnames":12}],3:[function(require,module,exports){
|
||||
var TreeActions, TreeStore, _load, code, div, recl, ref, span;
|
||||
|
||||
load = React.createFactory(require('./LoadComponent.coffee'));
|
||||
_load = require('./LoadComponent.coffee');
|
||||
|
||||
TreeStore = require('../stores/TreeStore.coffee');
|
||||
|
||||
@ -319,15 +326,25 @@ recl = React.createClass;
|
||||
|
||||
ref = React.DOM, div = ref.div, span = ref.span, code = ref.code;
|
||||
|
||||
module.exports = function(queries, Child) {
|
||||
module.exports = function(queries, Child, load) {
|
||||
if (load == null) {
|
||||
load = _load;
|
||||
}
|
||||
return recl({
|
||||
displayName: "Async",
|
||||
getInitialState: function() {
|
||||
return this.stateFromStore();
|
||||
},
|
||||
_onChangeStore: function() {
|
||||
return this.setState(this.stateFromStore());
|
||||
},
|
||||
getPath: function() {
|
||||
var ref1;
|
||||
return (ref1 = this.props.dataPath) != null ? ref1 : TreeStore.getCurr();
|
||||
},
|
||||
stateFromStore: function() {
|
||||
var path, ref1;
|
||||
path = (ref1 = this.props.dataPath) != null ? ref1 : TreeStore.getCurr();
|
||||
return {
|
||||
path: path,
|
||||
got: TreeStore.fulfill(path, queries)
|
||||
got: TreeStore.fulfill(this.getPath(), queries)
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
@ -338,8 +355,14 @@ module.exports = function(queries, Child) {
|
||||
return TreeStore.removeChangeListener(this._onChangeStore);
|
||||
},
|
||||
componentDidUpdate: function(_props, _state) {
|
||||
if (_props !== this.props) {
|
||||
this.setState(this.stateFromStore());
|
||||
}
|
||||
return this.checkPath();
|
||||
},
|
||||
checkPath: function() {
|
||||
return TreeActions.getPath(this.getPath(), this.filterQueries());
|
||||
},
|
||||
filterQueries: function() {
|
||||
return this.filterWith(this.state.got, queries);
|
||||
},
|
||||
@ -350,7 +373,7 @@ module.exports = function(queries, Child) {
|
||||
}
|
||||
request = {};
|
||||
for (k in _queries) {
|
||||
if (have[k] == null) {
|
||||
if (have[k] === void 0) {
|
||||
request[k] = _queries[k];
|
||||
}
|
||||
}
|
||||
@ -373,19 +396,12 @@ module.exports = function(queries, Child) {
|
||||
return request;
|
||||
}
|
||||
},
|
||||
checkPath: function() {
|
||||
return TreeActions.getPath(this.state.path, this.filterQueries());
|
||||
},
|
||||
getInitialState: function() {
|
||||
return this.stateFromStore();
|
||||
},
|
||||
_onChangeStore: function() {
|
||||
return this.setState(this.stateFromStore());
|
||||
},
|
||||
render: function() {
|
||||
return div({}, this.filterQueries() != null ? div({
|
||||
className: "loading"
|
||||
}, load({}, "")) : React.createElement(Child, _.merge(this.props, this.state.got), this.props.children));
|
||||
if (this.filterQueries() != null) {
|
||||
return React.createElement(load, this.props);
|
||||
} else {
|
||||
return React.createElement(Child, _.merge({}, this.props, this.state.got), this.props.children);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -591,8 +607,10 @@ module.exports = recl({
|
||||
},
|
||||
render: function() {
|
||||
return div({
|
||||
className: "loading"
|
||||
}, div({
|
||||
className: "spin state-" + this.state.anim
|
||||
}, "");
|
||||
}, ""));
|
||||
}
|
||||
});
|
||||
|
||||
@ -631,21 +649,19 @@ module.exports = recl({
|
||||
render: function() {
|
||||
return this.walk(this.props.manx);
|
||||
},
|
||||
walk: function(obj, key) {
|
||||
var ref1;
|
||||
walk: function(elem, key) {
|
||||
var ref1, ref2;
|
||||
switch (false) {
|
||||
case !(obj == null):
|
||||
return span({
|
||||
className: "loading"
|
||||
}, load({}, ""));
|
||||
case typeof obj !== "string":
|
||||
return obj;
|
||||
case obj.gn == null:
|
||||
return React.createElement((ref1 = components[obj.gn]) != null ? ref1 : obj.gn, $.extend({
|
||||
case !(elem == null):
|
||||
return load({}, "");
|
||||
case typeof elem !== "string":
|
||||
return elem;
|
||||
case elem.gn == null:
|
||||
return React.createElement((ref1 = components[elem.gn]) != null ? ref1 : elem.gn, $.extend({
|
||||
key: key
|
||||
}, obj.ga), obj.c.map(this.walk));
|
||||
}, elem.ga), (ref2 = elem.c) != null ? ref2.map(this.walk) : void 0);
|
||||
default:
|
||||
throw "Bad react-json " + (JSON.stringify(obj));
|
||||
throw "Bad react-json " + (JSON.stringify(elem));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1249,7 +1265,7 @@ EventEmitter = require('events').EventEmitter;
|
||||
|
||||
MessageDispatcher = require('../dispatcher/Dispatcher.coffee');
|
||||
|
||||
clog = console.log;
|
||||
clog = console.log.bind(console);
|
||||
|
||||
_tree = {};
|
||||
|
||||
@ -1274,39 +1290,6 @@ TreeStore = _.extend(EventEmitter.prototype, {
|
||||
pathToArr: function(_path) {
|
||||
return _path.split("/");
|
||||
},
|
||||
filterQuery: function(query) {
|
||||
return this.filterWith(this.fulfill(_curr, query), query);
|
||||
},
|
||||
filterWith: function(have, query) {
|
||||
var _query, k, kid, ref;
|
||||
if (have == null) {
|
||||
return query;
|
||||
}
|
||||
_query = {};
|
||||
for (k in query) {
|
||||
if (have[k] == null) {
|
||||
_query[k] = query[k];
|
||||
}
|
||||
}
|
||||
if ((query.kids != null) && (have.kids != null)) {
|
||||
if (_.isEmpty(have.kids)) {
|
||||
_query.kids = query.kids;
|
||||
} else {
|
||||
_query.kids = {};
|
||||
ref = have.kids;
|
||||
for (k in ref) {
|
||||
kid = ref[k];
|
||||
_.merge(_query.kids, this.filterWith(kid, query.kids));
|
||||
}
|
||||
if (_.isEmpty(_query.kids)) {
|
||||
delete _query.kids;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_.isEmpty(_query)) {
|
||||
return _query;
|
||||
}
|
||||
},
|
||||
fulfill: function(path, query) {
|
||||
var data, i, k, len, ref, ref1, ref2, ref3;
|
||||
data = this.fulfillLocal(path, query);
|
||||
|
@ -1,7 +1,7 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
MessageDispatcher = require '../dispatcher/Dispatcher.coffee'
|
||||
clog = console.log
|
||||
clog = console.log.bind(console)
|
||||
|
||||
_tree = {}
|
||||
_cont = {}
|
||||
@ -16,23 +16,6 @@ TreeStore = _.extend EventEmitter.prototype, {
|
||||
emitChange: -> @emit 'change'
|
||||
|
||||
pathToArr: (_path) -> _path.split "/"
|
||||
|
||||
filterQuery: (query)-> @filterWith (@fulfill _curr, query), query
|
||||
filterWith: (have,query)->
|
||||
return query unless have?
|
||||
_query = {}
|
||||
for k of query
|
||||
_query[k] = query[k] unless have[k]?
|
||||
if query.kids? and have.kids?
|
||||
if _.isEmpty have.kids
|
||||
_query.kids = query.kids
|
||||
else
|
||||
_query.kids = {}
|
||||
for k,kid of have.kids
|
||||
_.merge _query.kids, @filterWith kid, query.kids
|
||||
if _.isEmpty _query.kids
|
||||
delete _query.kids
|
||||
_query unless _.isEmpty _query
|
||||
|
||||
fulfill: (path,query)->
|
||||
data = @fulfillLocal path, query
|
||||
@ -96,6 +79,7 @@ TreeStore = _.extend EventEmitter.prototype, {
|
||||
{gn:'div', c:[
|
||||
{gn:'pre', c:[@getCurr()]}
|
||||
{gn:'span', c:['is either empty or does not exist.']}
|
||||
# {gn:'list'} XX handle empty snip
|
||||
] }]
|
||||
_got_snip[path] = true
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
++ query
|
||||
$% [%kids p=(list query)]
|
||||
[%name %t]
|
||||
[%path %t]
|
||||
[%snip %r]
|
||||
[%head %r]
|
||||
[%body %r]
|
||||
@ -49,6 +50,7 @@
|
||||
:- -.a
|
||||
?- -.a
|
||||
%name (from-type +.a ?^(s.bem i.s.bem q.bem))
|
||||
%path (from-type +.a (crip (spud (flop s.bem))))
|
||||
%head (from-type +.a head.dat)
|
||||
%snip (from-type +.a snip.dat)
|
||||
%meta (from-type +.a meta.dat)
|
||||
|
Loading…
Reference in New Issue
Block a user