Some long links to test with:
Created
February 14, 2018 23:30
-
-
Save dead-claudia/5ac08b4be95dfeb9bbf70c8c1a4d069f to your computer and use it in GitHub Desktop.
Flems test links
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"middle": 39.01, | |
"files": [ | |
{ | |
"name": ".html", | |
"content": "\n" | |
}, | |
{ | |
"name": ".js", | |
"content": "// https://github.com/pakx/mithril-hn-basic\nvar settings = {\n apiHost : \"https://node-hnapi.herokuapp.com\"\n , routesDesc : [\n {name:\"news\", pagesMax:15, cacheMax:15, isMenu: true}\n , {name: \"show\", pagesMax: 3, cacheMax:3, isMenu: true}\n , {name: \"ask\", pagesMax: 3, cacheMax:3, isMenu: true}\n , {name: \"jobs\", pagesMax: 1, cacheMax:1, isMenu: true}\n , {name: \"item\", pagesMax: 0, cacheMax:10, isMenu: false}\n , {name: \"user\", pagesMax:0, cacheMax:10, isMenu: false}\n ]\n}\n\n/// Returns idempotent view-function that renders UI per passed-in model\nvar view = (function() {\n\n function view(model, actions) {\n return vwApp(model, actions)\n }\n\n function vwApp(model, actions) {\n return m(\".app\"\n , vwAppHeader(model, actions)\n , vwAppBody(model, actions)\n )\n }\n\n function vwAppHeader(model, actions) {\n return m(\".app-header\"\n , m(\"a[href='/']\"\n , {oncreate:m.route.link}\n , m(\"img.logo\"\n , { src: \"https://mithril.js.org/logo.svg\"\n , alt: \"Mithril Logo\"\n }\n )\n )\n // navigable-to category links:\n , Object.keys(model.routesInfo)\n .filter(function(key) {\n return model.routesInfo[key].isMenu\n })\n .map(function(key) {\n var itm = model.routesInfo[key]\n , cls = itm.name == model.routeName ? \".active\" : \"\"\n , href = \"/\" + itm.name + \"/1\"\n return m(\"a\" + cls\n , { href: href, oncreate: m.route.link }\n , itm.name\n )\n })\n )\n }\n\n function vwAppBody(model, actions) {\n return m(\".body\"\n , model.displayFor.match(/[CI]/) ? vwItem(model, actions)\n : model.displayFor == \"U\" ? vwUser(model, actions)\n : vwPage(model, actions)\n )\n }\n\n function vwItem(model, actions) {\n return m(\".item\"\n , m(\".item-controls\", vwLinkHistoryBack())\n , vwItemBody(model, actions)\n )\n }\n\n function vwItemBody(model, actions) {\n var item = actions.getData(\"item\", model.displayForId)\n return ! item\n ? m(\".item-body\", \"Loading ...\")\n : m(\".item-body\"\n , m(\".item-title\", item.title)\n , m(\".item-content\", m.trust(item.content))\n , item.comments \n ? [ m(\".label-comments\", \"Comments\")\n , m(\"ul.tree\", vwItemComments(item.comments, actions))\n ]\n : m(\".label-comments-none\", \"(No Comments)\")\n )\n }\n\n function vwItemComments(comments, actions) {\n return m(\".comments\"\n , comments.map(function(itm) {\n var user = itm.user || \"\"\n , userHref = actions.getUserHref(itm)\n return m(\"li\"\n , m(\".comment\"\n , m(\".annotations\"\n , user ? m(\"a.user\"\n , { href: userHref, oncreate: m.route.link}\n , itm.user\n )\n : m(\"span.user\", \"(n/a)\")\n , m(\".time-ago\", itm.time_ago)\n )\n , m(\".item-content\", m.trust(itm.content))\n , itm.comments\n ? m(\"ul\", vwItemComments(itm.comments, actions))\n : \"\"\n )\n )\n })\n )\n }\n\n function vwUser(model, actions) {\n var user = actions.getData(\"user\", model.displayForId)\n return ! user \n ? m(\".user\", \"Loading ...\")\n : m(\".user\"\n , m(\".user-controls\", vwLinkHistoryBack())\n , m(\".user-id\", \"User: \", user.id)\n , m(\".user-joined\", \"Joined: \", user.created)\n , m(\".user-karma\", \"Karma: \", user.karma)\n )\n }\n\n function vwPage(model, actions) {\n return m(\".posts\"\n , vwPageHeader(model, actions)\n , vwPageBody(model, actions)\n )\n }\n\n function vwPageHeader(model, actions) {\n var routeInfo = model.routesInfo[model.routeName]\n return m(\".posts-controls\"\n , m(\"button\"\n , { disabled: routeInfo.pageNum <= 1\n , onclick: actions.onPrev\n }\n , \"< Prev\"\n )\n , m(\"span\"\n , \"(\", model.routeName, \") \"\n , routeInfo.pageNum, \"/\", routeInfo.pagesMax\n )\n , m(\"button\"\n , { disabled: routeInfo.pageNum >= routeInfo.pagesMax\n , onclick: actions.onNext\n }\n , \"Next >\"\n )\n )\n }\n\n function vwPageBody(model, actions) {\n var pageNum = model.routesInfo[model.routeName].pageNum\n , startNum = (pageNum - 1) * model.postsPerPage + 1\n , posts = actions.getData(model.routeName, pageNum)\n\n return ! posts\n ? m(\".posts-body\", \"Loading...\")\n : m(\".posts-body\"\n , m(\"ol\"\n , { start: startNum }\n , posts.map(function(itm) {\n return m(\"li\", vwPostBody(itm, actions))\n })\n )\n )\n }\n\n function vwPostBody(post, actions) {\n var postInfo = actions.getPostInfo(post)\n , userHref = actions.getUserHref(post)\n , commentsHref = actions.getCommentsHref(post)\n , attrs = Object.assign({ href: postInfo.url }\n , postInfo.isRoutable ? {oncreate: m.route.link} : {}\n )\n\n return m(\".post\"\n , m(\"a\", attrs, post.title)\n , m(\".annotations\"\n , post.points == null ? \"\"\n : m(\".post-points\"\n , post.points + \" point\" + (post.points == 1 ? \"\" : \"s\")\n )\n , post.user == null ? \"\"\n : [ \"by \"\n , m(\"a.user\"\n , { href: userHref, oncreate: m.route.link}\n , post.user\n )\n ]\n , m(\".time-ago\", post.time_ago)\n , \" | \"\n , m(\".post-comments-count\"\n , post.comments_count > 0\n ? m(\"a\"\n , { href: commentsHref, oncreate: m.route.link}\n , post.comments_count + \" comment\"\n + (post.comments_count == 1 ? \"\" : \"s\")\n )\n : \"0 comments\"\n )\n )\n )\n }\n\n function vwLinkHistoryBack(label) {\n return m(\"a[href='#']\"\n , { onclick: function(e) {\n e.preventDefault()\n window.history.back()\n }}\n , label || \"Go Back\"\n )\n }\n\n return view\n})()\n\n/// Returns object encapsulating app-behavior\nfunction createActions(model, dataApi) {\n return {\n onNavigateTo : onNavigateTo\n , onPrev : onPrev\n , onNext : onNext\n , getData : getData\n , getPostInfo : getPostInfo\n , getUserHref : getUserHref\n , getCommentsHref : getCommentsHref\n }\n\n function onNavigateTo(routeName, params) {\n var routeInfo = model.routesInfo[routeName]\n , id = params.id\n\n model.displayFor = routeName == \"comment\" ? \"C\"\n : routeName == \"item\" ? \"I\"\n : routeName == \"user\" ? \"U\"\n : \"O\" // other\n\n if (model.displayFor.match(/[CI]/)) {\n model.displayForId = id\n if (! getData(routeName, id)) {\n fetchItem(routeName, id)\n }\n } else if (model.displayFor == \"U\") {\n model.displayForId = id\n if (! getData(routeName, id)) {\n fetchUser(routeName, id)\n }\n } else if (isNaN(id) || +id < 0 || +id > routeInfo.pagesMax) {\n m.route.set(\"/\" + routeName + \"/1\")\n return\n\n } else {\n model.routeName = routeName\n routeInfo.pageNum = +id\n if (! getData(routeName, id)) {\n fetchPage(routeName, id)\n }\n }\n }\n\n function onPrev() {\n var pageNum = model.routesInfo[model.routeName].pageNum\n if (pageNum > 1) {\n m.route.set(\"/\" + model.routeName + \"/\" + (pageNum - 1))\n } \n }\n\n function onNext() {\n var pageNum = model.routesInfo[model.routeName].pageNum\n if (pageNum < model.routesInfo[model.routeName].pagesMax) {\n m.route.set(\"/\" + model.routeName + \"/\" + (pageNum + 1))\n } \n }\n\n function getData(routeName, id) {\n return model.routesInfo[routeName].cache.vals[id]\n }\n\n function fetchPage(routeName, pageNum) {\n var routeInfo = model.routesInfo[routeName]\n return dataApi.fetchPage(routeName, pageNum)\n .then(function(data) {\n if (data.length) {\n routeInfo.cache.vals[pageNum] = data\n routeInfo.cache.keys.push(pageNum)\n if (data.length < model.postsPerPage) {\n routeInfo.pagesMax = \n Math.max.apply(null, routeInfo.cache.keys)\n }\n }\n })\n .catch(function(err) {\n console.error(err)\n })\n }\n\n function fetchItem(routeName, id) {\n var routeInfo = model.routesInfo[routeName]\n return dataApi.fetchItem(id)\n .then(function(data) {\n routeInfo.cache.vals[id] = data\n routeInfo.cache.keys.push(id)\n // trim cache size to routeInfo.cacheMax\n if (routeInfo.cache.keys.length > routeInfo.cacheMax) {\n delete routeInfo.cache.vals[routeInfo.cache.keys[0]]\n routeInfo.cache.keys = routeInfo.cache.keys.slice(1)\n }\n })\n .catch(function(err) {\n console.error(err)\n })\n }\n\n function fetchUser(routeName, id) {\n var routeInfo = model.routesInfo[routeName]\n return dataApi.fetchUser(id)\n .then(function(data) {\n routeInfo.cache.vals[id] = data\n routeInfo.cache.keys.push(id)\n // trim cache size to routeInfo.cacheMax\n if (routeInfo.cache.keys.length > routeInfo.cacheMax) {\n delete routeInfo.cache.vals[routeInfo.cache.keys[0]]\n routeInfo.cache.keys = routeInfo.cache.keys.slice(1)\n }\n })\n .catch(function(err) {\n console.error(err)\n })\n }\n\n function getPostInfo(post) {\n var matches = post.url.match(/^item\\?id=(\\d+)/i)\n return {\n url : matches ? \"/item/\" + matches[1] : post.url\n , isRoutable: matches != null\n }\n }\n\n function getUserHref(itm) {\n return itm.user ? \"/user/\" + itm.user : \"\"\n }\n\n function getCommentsHref(post) {\n return \"/item/\" + post.id\n }\n\n function delay(ms) {\n return new Promise(function(resolve) {\n setTimeout(resolve, ms)\n })\n }\n}\n\n/// Returns object modeling entire app as data\nfunction createModel(settings) {\n return {\n // name of curent route\n routeName: settings.routesDesc[0].name\n\n // data associated w/ each route-name\n // we cache entities previously accessed, up to a max per cache\n , routesInfo: settings.routesDesc.reduce(function(acc, itm){\n var routeInfo = {pageNum: 1, cache: {keys:[], vals:{}}}\n acc[itm.name] = Object.assign(routeInfo, itm)\n return acc\n }, {})\n\n // type of entity to display\n // one of C|I|U|O = comment/item/user/other\n , displayFor: undefined\n\n // id of entity to display; applies to C|I|U\n , displayForId: undefined\n\n , postsPerPage : 30\n }\n}\n\nfunction createRouteResolver(settings, model, actions) {\n return settings.routesDesc.reduce(function(acc, itm){\n acc[\"/\" + itm.name + \"/:id\"] = {\n onmatch: function(params, route) {\n actions.onNavigateTo(itm.name, params)\n }\n , render: function() {\n return view(model, actions)\n }\n }\n return acc\n }, {})\n}\n\n/// Returns object encapsulating external data access\nfunction createDataApi(settings) {\n return {\n fetchPage: function(routeName, pageNum) {\n return m.request({\n type: \"GET\"\n , url: settings.apiHost\n + \"/\" + routeName + \"?page=\" + pageNum\n })\n }\n , fetchItem: function(id) {\n return m.request({\n type: \"GET\"\n , url: settings.apiHost + \"/item/\" + id\n })\n }\n , fetchUser: function(id) {\n return m.request({\n type: \"GET\"\n , url: settings.apiHost + \"/user/\" + id\n })\n }\n }\n}\n\n var model = createModel(settings)\n , dataApi = createDataApi(settings)\n , actions = createActions(model, dataApi)\n , routeResolver = createRouteResolver(settings, model, actions)\n , defaultRoute = \"/\" + settings.routesDesc[0].name + \"/1\"\n\n m.route(document.body, defaultRoute, routeResolver)" | |
}, | |
{ | |
"name": ".css", | |
"content": ".logo {height:16px;}\n.app-header a {margin:0px 2px;}\n.active {background-color:yellow;font-weight:bold;}\n.annotations > * {display:inline-block;}\n.post-points {margin-right:0.5em;}\n.time-ago {margin-left:0.5em;}\n.label-comments {font-weight:bold;margin:5px 0px;}\n.label-comments-none {color:gray;margin:5px 0px;}\n.comment {border:1px solid white;margin-left:5px;position:relative;top:-1.5em;width:100%;}\n.comment > .annotations {background-color: #eaecee;padding:3px;margin:0px;}\n\n/* Tree-structure CSS adapted from https://gist.github.com/dylancwood/7368914 */\nul.tree, ul.tree ul {list-style: none;margin: 0;padding: 0;} \nul.tree ul {margin-left: 10px;}\nul.tree li {border-left:1px solid rgb(100,100,100);line-height: 20px;margin: 0;padding: 0 7px;}\nul.tree li:last-child {border-left:none;}\nul.tree li:before {border-bottom:1px solid rgb(100,100,100);color:white;content:\"\";display:inline-block;height:1em;left:-7px;position:relative;top:-0.3em;width:12px;}\nul.tree li:last-child:before {border-left:1px solid rgb(100,100,100);}" | |
} | |
], | |
"links": [ | |
{ | |
"name": "mithril.js", | |
"url": "https://unpkg.com/mithril/mithril.js", | |
"type": "js" | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment