coffeescript-ui
Version:
Coffeescript User Interface System
339 lines (269 loc) • 7.5 kB
text/coffeescript
###
* coffeescript-ui - Coffeescript User Interface System (CUI)
* Copyright (c) 2013 - 2016 Programmfabrik GmbH
* MIT Licence
* https://github.com/programmfabrik/coffeescript-ui, http://www.coffeescript-ui.org
###
#
class CUI.DocumentBrowser.Node extends CUI.ListViewTreeNode
readOpts: ->
super()
=
if .endsWith("/")
= .substr(0, .length-1)
# console.debug ,
initOpts: ->
super()
browser:
mandatory: true
check: CUI.DocumentBrowser
url:
check: (v) ->
!!CUI.parseLocation(v)
path:
default: []
check: Array
title:
check: String
getChildren: ->
if .leaf
return []
if
new CUI.resolvedPromise()
else
__loadChildren: (dive = true) ->
dive = true
dfr = new CUI.Deferred()
xhr = new CUI.XHR
url: +
responseType: "text"
xhr.start()
.done (data) =>
if data.startsWith("<") # assume HTML, something isnt right
.leaf = true
dfr.resolve([])
return
# console.debug
children = []
items = []
for row in data.split("\n")
m = row.match(/^\s*(\S+?)(|=(\S+))\s*$/)
if not m
continue
# console.debug "match:", CUI.util.dump(m)
info = m[1].split(":")
if m[3]
title = m[3]
else
title = info[0]
path = .slice(0)
path.push(info[0])
items.push
title: title
path: path
if items.length == 0
.leaf = true
dfr.resolve([])
return
children_done = 0
for item, idx in items
child = new CUI.DocumentBrowser.Node
browser:
url:
title: item.title
path: item.path
children.push(child)
if dive
child.__loadChildren(false)
.always =>
children_done = children_done + 1
if children_done == items.length
= children
dfr.resolve(children)
if not dive
dfr.resolve(children)
return
.fail =>
.leaf = true
dfr.resolve([])
dfr.promise()
getMainArticleUrl: ->
+
loadIncludes: (content, nodePath, includes=[]) ->
dfr = new CUI.Deferred()
new_includes = includes.slice(0)
load_next_include = =>
match = content.match(/@\(\s*(.*?)\s*\)/)
# console.debug "loading next", content, match
if not match
dfr.resolve(content)
return
url =
# console.info("Including:", url, "From:", nodePath)
replace_in_content = (replace_content) =>
arr = [
content.substr(0, match.index)
content.substr(match.index + match[0].length)
]
arr.splice(1, 0, replace_content)
content = arr.join("")
load_next_include()
if url in includes
replace_in_content("**(Recursion: "+match[1]+")**")
# recursion protection, ignore this
else
new_includes.push(url)
new CUI.XHR
url: + url
responseType: "text"
.start()
.done (include_content) =>
parts = url.split("/")
parts.pop()
.done (_content) =>
replace_in_content(_content)
.fail =>
replace_in_content("**(Error: "+match[1]+")**")
return
load_next_include()
return dfr.promise()
loadContent: ->
if
new CUI.resolvedPromise(, , )
dfr = new CUI.Deferred()
new CUI.XHR
url:
responseType: "text"
.start()
.done () =>
if .startsWith("<")
dfr.reject()
return
.fail(dfr.reject)
.done (content) =>
.marked(@, content)
.done (content) =>
= CUI.dom.htmlToNodes(content)
= CUI.dom.findTextInNodes()
.addWords()
# console.debug "loaded:", filename, markdown.length, .length
dfr.resolve(, , )
.fail(dfr.reject)
.fail(dfr.reject)
dfr.promise()
findContent: (searchQuery, matches = []) ->
CUI.util.assert(searchQuery instanceof CUI.DocumentBrowser.SearchQuery, "DocumentBrowserNode.findContent", "searchQuery needs to be instance of CUI.DocumentBrowser.SearchQuery.", searchQuery: searchQuery)
regExpe = searchQuery.getRegExps()
idx_hits = [0..regExpe.length-1]
remove_matched_part = (match) =>
if idx_hits.length == 0
return
for _match in match.getMatches()
CUI.util.removeFromArray(_match.regExp_idx, idx_hits)
if idx_hits.length == 0
return
title_match = searchQuery.match()
if title_match
remove_matched_part(title_match)
text_matches = []
if
for text, idx in
text_match = searchQuery.match(text)
if not text_match
continue
text_match.nodeIdx = idx
text_matches.push(text_match)
remove_matched_part(text_match)
if idx_hits.length == 0
# console.debug "findContent", title_match, text_matches
matches.push(new CUI.DocumentBrowser.NodeMatch(
node: @
searchQuery: searchQuery
title_match: title_match
text_matches: text_matches
))
# console.debug "pusing:", matches.length, row_matches, title_match
# console.debug +" matches:", matches1, matches2
if
for c in
c.findContent(searchQuery, matches)
return matches
getBrowser: ->
selectLocation: (nodePath, dfr = new CUI.Deferred()) ->
# console.debug "selectLocation", nodePath, "us:",
if nodePath ==
dfr.resolve(@)
return
select_child = =>
if .leaf
dfr.fail(@)
for c in
# console.debug c.getNodePath()
if nodePath.startsWith(c.getNodePath()+"/") or nodePath == c.getNodePath()
c.selectLocation(nodePath, dfr)
return
console.error("Unable to find:", nodePath, "in", )
dfr.fail()
if
select_child()
else
.always =>
select_child()
dfr
getLastPathElement: ->
[.length-1]
getNodePath: (filename) ->
nodePath = "/"+.join("/")
if not filename
nodePath
else if nodePath == "/"
nodePath + filename
else
nodePath + "/" + filename
getTitlePath: ->
texts = []
for node in
if node.isRoot()
continue
texts.push(node.getTitle())
texts
getTitle: ->
absoluteUrl: (base, relative) ->
stack = base.split("/")
parts = relative.split("/")
for part in parts
if part == "."
continue
if part == ".."
stack.pop()
else
stack.push(part)
stack.join("/")
rendererLink: (href, title, text) ->
title = href
href = .renderHref(href, )
"<a href='"+href+"' title='"+CUI.escapeAttribute(title)+"'>"+text+"</a>"
rendererImage: (href, title, text) ->
if href.startsWith("http:") or href.startsWith("//")
url = null
else if href.startsWith("/")
url =
else
url = +
if url != null
_href =
else
_href = href
# console.debug @, , , _href, href, title, text
"<img src='"+_href+"' alt='"+CUI.escapeAttribute(text)+"' title='"+CUI.escapeAttribute(title)+"'></img>"
renderContent: ->
new CUI.Label(text: , multiline: true)
class CUI.DocumentBrowser.RootNode extends CUI.DocumentBrowser.Node