├── .nojekyll ├── favicon.ico ├── .travis.yml ├── img ├── apple-touch-icon-114x114.png ├── apple-touch-icon-144x144.png ├── apple-touch-startup-image-320x460.png ├── apple-touch-startup-image-640x1096.png ├── apple-touch-startup-image-640x920.png └── apple-touch-startup-image-640x1096.png.png ├── .gitignore ├── css ├── boot.less ├── labels.less ├── home.less ├── side.less ├── pull2refresh.less ├── issuelist.less ├── issues.less ├── github.less ├── menu.less ├── main.less ├── markdown.less └── normalize.less ├── .jshintrc ├── LICENSE ├── package.json ├── js ├── home.js ├── labels.js ├── side.js ├── issuelist.js ├── menu.js ├── issues.js ├── lib │ ├── detect.js │ ├── touch.js │ ├── template.js │ ├── highlight.js │ └── marked.js ├── boot.js └── pull2refresh.js ├── Gruntfile.js ├── index.html ├── dev.html ├── README.md └── dist └── main.min.css /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/favicon.ico -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | before_script: 5 | - npm install -g grunt-cli -------------------------------------------------------------------------------- /img/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /img/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /img/apple-touch-startup-image-320x460.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-startup-image-320x460.png -------------------------------------------------------------------------------- /img/apple-touch-startup-image-640x1096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-startup-image-640x1096.png -------------------------------------------------------------------------------- /img/apple-touch-startup-image-640x920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-startup-image-640x920.png -------------------------------------------------------------------------------- /img/apple-touch-startup-image-640x1096.png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaoda/spring/HEAD/img/apple-touch-startup-image-640x1096.png.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .svn/ 13 | *.swp 14 | .project 15 | .settings/ 16 | node_modules/ 17 | _site/ 18 | -------------------------------------------------------------------------------- /css/boot.less: -------------------------------------------------------------------------------- 1 | @import "normalize"; 2 | @import "github"; 3 | @import "main"; 4 | @import "markdown"; 5 | @import "pull2refresh"; 6 | @import "issuelist"; 7 | @import "side"; 8 | @import "menu"; 9 | @import "home"; 10 | @import "labels"; 11 | @import "issues"; -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi" : true, 3 | "boss" : true, 4 | "browser" : true, 5 | "curly" : false, 6 | "debug" : true, 7 | "devel" : true, 8 | "eqeqeq" : false, 9 | "eqnull" : true, 10 | "expr" : true, 11 | "laxbreak" : true, 12 | "laxcomma" : true, 13 | "validthis": true, 14 | "multistr" : true 15 | } -------------------------------------------------------------------------------- /css/labels.less: -------------------------------------------------------------------------------- 1 | .spa-page-labels { 2 | .container { 3 | top: 3em; 4 | 5 | @media screen and (min-width: @screen-tablet) { 6 | top: 0; 7 | } 8 | 9 | .container-inner { 10 | @media screen and (min-width: @screen-tablet) { 11 | margin-left: 16em; 12 | } 13 | 14 | @media screen and (min-width: @screen-desktop) { 15 | margin-left: 18em; 16 | margin-right: 1em; 17 | } 18 | 19 | @media screen and (min-width: @screen-large) { 20 | margin-left: 24em; 21 | max-width: 52em; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /css/home.less: -------------------------------------------------------------------------------- 1 | .spa-page-home { 2 | .container { 3 | top: 3em; 4 | 5 | @media screen and (min-width: @screen-tablet) { 6 | top: 0; 7 | 8 | .desc { 9 | display: none; 10 | } 11 | } 12 | 13 | .container-inner { 14 | 15 | @media screen and (min-width: @screen-tablet) { 16 | margin-left: 16em; 17 | } 18 | 19 | @media screen and (min-width: @screen-desktop) { 20 | margin-left: 18em; 21 | margin-right: 1em; 22 | } 23 | 24 | @media screen and (min-width: @screen-large) { 25 | margin-left: 24em; 26 | max-width: 52em; 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /css/side.less: -------------------------------------------------------------------------------- 1 | .side { 2 | display: none; 3 | position: absolute; 4 | left: 0; 5 | top: 0; 6 | bottom: 0; 7 | width: 15em; 8 | z-index: 3000; 9 | box-shadow: 0 0 4px @greyer; 10 | 11 | @media screen and (min-width: @screen-tablet) { 12 | display: block; 13 | } 14 | 15 | @media screen and (min-width: @screen-desktop) { 16 | width: 16em; 17 | } 18 | 19 | @media screen and (min-width: @screen-large) { 20 | width: 18em; 21 | left: 4em; 22 | } 23 | 24 | .container { 25 | background: @lighter; 26 | 27 | .logo { 28 | margin: 20px 10px; 29 | font-size: 3em; 30 | } 31 | 32 | .desc { 33 | box-shadow: none; 34 | 35 | a { 36 | color: @greyer; 37 | } 38 | } 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /css/pull2refresh.less: -------------------------------------------------------------------------------- 1 | .pulldown, .pullup { 2 | position: absolute; 3 | width: 100%; 4 | height: 3em; 5 | line-height: 3em; 6 | text-align: center; 7 | color: @light; 8 | font-weight: 100; 9 | z-index: 1; 10 | 11 | .ball { 12 | display: inline-block; 13 | padding: 5px; 14 | .border-radius(50%); 15 | } 16 | 17 | .ball:nth-child(1) { 18 | background: @orange; 19 | -webkit-animation: move-left 800ms ease-in-out infinite alternate; 20 | } 21 | 22 | .ball:nth-child(2) { 23 | background: @blue; 24 | -webkit-animation: move-right 800ms ease-in-out infinite alternate; 25 | } 26 | } 27 | 28 | .pulldown { 29 | top: -3em; 30 | } 31 | 32 | .pullup { 33 | bottom: -3em; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 zhaoda(赵达) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spring", 3 | "title": "Spring", 4 | "version": "0.1.0", 5 | "description": "Spring is a blog engine written by github issues", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/zhaoda/spring" 9 | }, 10 | "keywords": [ 11 | "spring", 12 | "blog", 13 | "spa", 14 | "webapp", 15 | "javascript", 16 | "less" 17 | ], 18 | "author": { 19 | "name": "zhaoda", 20 | "email": "zd6437@gmail.com", 21 | "url": "http://zhaoda.net" 22 | }, 23 | "license": { 24 | "type": "MIT", 25 | "url": "https://raw.github.com/zhaoda/spring/master/LICENSE" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/zhaoda/spring/issues" 29 | }, 30 | "homepage": "http://zhaoda.net/spring", 31 | "devDependencies": { 32 | "grunt": "~0.4.2", 33 | "grunt-contrib-clean": "~0.5.0", 34 | "grunt-contrib-concat": "~0.4.0", 35 | "grunt-contrib-jshint": "~0.10.0", 36 | "grunt-contrib-copy": "~0.5.0", 37 | "grunt-contrib-uglify": "~0.4.0", 38 | "grunt-contrib-less": "~0.11.0" 39 | }, 40 | "scripts": { 41 | "test": "grunt" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /css/issuelist.less: -------------------------------------------------------------------------------- 1 | .issuelist { 2 | position: relative; 3 | 4 | article { 5 | margin: 0 10px; 6 | padding: 20px 0 10px; 7 | box-shadow: 0 1px 0 @lighter; 8 | 9 | span.date { 10 | display: block; 11 | padding: 0 0 5px 0; 12 | color: @light; 13 | font-size: 0.75em; 14 | font-weight: 200; 15 | 16 | @media screen and (min-width: @screen-small) { 17 | font-size: 1em; 18 | } 19 | } 20 | 21 | h3 { 22 | margin: 0; 23 | font-weight: normal; 24 | 25 | @media screen and (min-width: @screen-small) { 26 | font-size: 2em; 27 | } 28 | 29 | @media screen and (min-width: @screen-desktop) { 30 | font-size: 2.5em; 31 | } 32 | 33 | a { 34 | display: block; 35 | } 36 | } 37 | 38 | p.tag { 39 | margin: 0; 40 | padding: 5px 0; 41 | font-size: 0.75em; 42 | 43 | @media screen and (min-width: @screen-small) { 44 | font-size: 1em; 45 | } 46 | 47 | a { 48 | display: inline-block; 49 | margin-right: 5px; 50 | padding: 2px 5px; 51 | font-weight: 200; 52 | color: #fff; 53 | .border-radius(4px); 54 | background: @lighter; 55 | } 56 | } 57 | } 58 | 59 | .end { 60 | padding: 10px 0; 61 | text-align: center; 62 | color: @light; 63 | font-weight: 100; 64 | } 65 | } -------------------------------------------------------------------------------- /js/home.js: -------------------------------------------------------------------------------- 1 | ;(function($, win, doc) { 2 | 'use strict'; 3 | 4 | var $doc = $(document), 5 | spring = win.spring, 6 | source = '\ 7 |
\ 8 |

<%=$.spring.config.title%>

\ 9 | Menu\ 10 |
\ 11 |
\ 12 |
\ 13 | <%if($.spring.config.desc) {%>\ 14 |
<%=#marked($.spring.config.desc)%>
\ 15 | <%}%>\ 16 |
\ 17 |
\ 18 | \ 19 |
\ 20 |
\ 21 |
\ 22 |
', 23 | render = template.compile(source) 24 | 25 | var pageHome = { 26 | route: '', 27 | classname: 'home', 28 | animate: 'fadeIn', 29 | title: 'Spring', 30 | view: function(pageData) { 31 | var $page = this, 32 | data = {}, 33 | body = render(data) 34 | 35 | $doc.trigger('spa:initpage', [$page, {title: 'Spring', body: body}]) 36 | }, 37 | init: function(pageData) { 38 | var $view = this, 39 | $container = $('.container', $view), 40 | $issuelist = $('.issuelist', $container) 41 | 42 | $container.trigger('spa:scroll', {direction: 'y'}) 43 | 44 | $container.trigger('pull2refresh:init', { 45 | pullup: function() { 46 | $issuelist.trigger('issuelist:getdata', {pull: 'up', container: $container}) 47 | } 48 | }) 49 | 50 | $container.trigger('pull2refresh:pullup') 51 | } 52 | } 53 | 54 | $doc.trigger('spa:route', pageHome) 55 | 56 | })(Zepto, window, document) -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | 7 | // Task configuration. 8 | jshint: { 9 | options: { 10 | jshintrc: '.jshintrc' 11 | }, 12 | gruntfile: { 13 | src: 'Gruntfile.js' 14 | }, 15 | build: { 16 | src: 'js/*.js' 17 | } 18 | }, 19 | 20 | concat: { 21 | js: { 22 | options: { 23 | separator: ';' 24 | }, 25 | src: [ 26 | 'js/lib/zepto.js', 27 | 'js/lib/detect.js', 28 | 'js/lib/touch.js', 29 | 'js/lib/spa.js', 30 | 'js/lib/template.js', 31 | 'js/lib/marked.js', 32 | 'js/lib/highlight.js', 33 | 'js/boot.js', 34 | 'js/pull2refresh.js', 35 | 'js/issuelist.js', 36 | 'js/side.js', 37 | 'js/menu.js', 38 | 'js/home.js', 39 | 'js/labels.js', 40 | 'js/issues.js' 41 | ], 42 | dest: 'dist/main.js' 43 | } 44 | }, 45 | 46 | uglify: { 47 | js: { 48 | files: { 49 | 'dist/main.min.js': 'dist/main.js' 50 | } 51 | } 52 | }, 53 | 54 | less: { 55 | production: { 56 | options: { 57 | cleancss: true 58 | }, 59 | files: { 60 | 'dist/main.min.css': 'css/boot.less' 61 | } 62 | } 63 | }, 64 | 65 | clean: { 66 | temporary: ['dist/main.js', 'dest/main.min.css'] 67 | } 68 | 69 | }) 70 | 71 | // These plugins provide necessary tasks. 72 | grunt.loadNpmTasks('grunt-contrib-concat') 73 | grunt.loadNpmTasks('grunt-contrib-jshint') 74 | grunt.loadNpmTasks('grunt-contrib-uglify') 75 | grunt.loadNpmTasks('grunt-contrib-less') 76 | grunt.loadNpmTasks('grunt-contrib-clean') 77 | 78 | 79 | // Default task. 80 | grunt.registerTask( 81 | 'default', 82 | [ 83 | 'jshint', 84 | 'concat', 85 | 'uglify', 86 | 'less', 87 | 'clean' 88 | ]) 89 | 90 | // // Test task. 91 | grunt.registerTask('test', ['jshint']) 92 | 93 | } -------------------------------------------------------------------------------- /js/labels.js: -------------------------------------------------------------------------------- 1 | ;(function($, win, doc) { 2 | 'use strict'; 3 | 4 | var $doc = $(document), 5 | spring = win.spring, 6 | source = '\ 7 |
\ 8 |

<%=$.spring.config.title%>

\ 9 | Menu\ 10 |
\ 11 |
\ 12 |
\ 13 |

Labels / <%=label%>

\ 14 |
\ 15 |
\ 16 | \ 17 |
\ 18 |
\ 19 |
\ 20 |
', 21 | render = template.compile(source) 22 | 23 | var pageLabels = { 24 | route: 'labels/(:label)', 25 | classname: 'labels', 26 | animate: 'fadeIn', 27 | title: 'Spring', 28 | view: function(pageData) { 29 | var $page = this, 30 | label = pageData.requestData[0], 31 | data = {label: label}, 32 | body = render(data) 33 | 34 | if(!label) { 35 | $doc.trigger('spa:navigate', {hash: '', replace: true}) 36 | } 37 | 38 | $doc.trigger('spa:initpage', [$page, {title: $.spring.fn.encodeHtml(label), body: body}]) 39 | }, 40 | init: function(pageData) { 41 | var $view = this, 42 | $container = $('.container', $view), 43 | $issuelist = $('.issuelist', $container) 44 | 45 | $container.trigger('spa:scroll', {direction: 'y'}) 46 | 47 | $container.trigger('pull2refresh:init', { 48 | pullup: function() { 49 | $issuelist.trigger('issuelist:getdata', {pull: 'up', container: $container}) 50 | } 51 | }) 52 | 53 | $container.trigger('pull2refresh:pullup') 54 | }, 55 | afteropen: function(pageData) { 56 | } 57 | } 58 | 59 | $doc.trigger('spa:route', pageLabels) 60 | 61 | })(Zepto, window, document) -------------------------------------------------------------------------------- /css/issues.less: -------------------------------------------------------------------------------- 1 | .spa-page-issues { 2 | header { 3 | .btn-back { 4 | display: block; 5 | } 6 | } 7 | 8 | .container { 9 | top: 3em; 10 | 11 | @media screen and (min-width: @screen-tablet) { 12 | top: 0; 13 | } 14 | 15 | .container-inner { 16 | @media screen and (min-width: @screen-tablet) { 17 | margin-left: 16em; 18 | } 19 | 20 | @media screen and (min-width: @screen-desktop) { 21 | margin-left: 18em; 22 | margin-right: 1em; 23 | } 24 | 25 | @media screen and (min-width: @screen-large) { 26 | margin-left: 24em; 27 | max-width: 52em; 28 | } 29 | } 30 | } 31 | 32 | .btn-back { 33 | display: none; 34 | 35 | @media screen and (min-width: @screen-tablet) { 36 | display: block; 37 | position: fixed; 38 | top: 10px; 39 | right: 10px; 40 | z-index: 2; 41 | .opacity(0.8); 42 | } 43 | 44 | @media screen and (min-width: @screen-large) { 45 | left: 72em; 46 | top: 20px; 47 | right: auto; 48 | } 49 | } 50 | 51 | .btn-menu { 52 | display: none; 53 | } 54 | 55 | .issues { 56 | position: relative; 57 | 58 | .desc { 59 | text-align: center; 60 | } 61 | 62 | .title { 63 | padding: 0 10px; 64 | font-weight: normal; 65 | text-align: center; 66 | margin-bottom: 0.2em; 67 | 68 | @media screen and (min-width: @screen-desktop) { 69 | font-size: 2.5em; 70 | } 71 | } 72 | 73 | article { 74 | video { 75 | max-width: 100%; 76 | } 77 | 78 | @media screen and (min-width: @screen-small) { 79 | font-size: 1em; 80 | 81 | pre { 82 | font-size: 0.8em; 83 | } 84 | } 85 | 86 | @media screen and (min-width: @screen-desktop) { 87 | font-size: 1.2em; 88 | } 89 | 90 | .btn-view { 91 | display: block; 92 | width: 100%; 93 | padding: 0.5em 0; 94 | text-align: center; 95 | font-weight: 200; 96 | .border-radius(4px); 97 | color: @light; 98 | background: @lighter; 99 | text-decoration: none; 100 | } 101 | } 102 | 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /css/github.less: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; padding: 0.5em; 9 | color: #333; 10 | background: #f8f8f8 11 | } 12 | 13 | .hljs-comment, 14 | .hljs-template_comment, 15 | .diff .hljs-header, 16 | .hljs-javadoc { 17 | color: #998; 18 | font-style: italic 19 | } 20 | 21 | .hljs-keyword, 22 | .css .rule .hljs-keyword, 23 | .hljs-winutils, 24 | .javascript .hljs-title, 25 | .nginx .hljs-title, 26 | .hljs-subst, 27 | .hljs-request, 28 | .hljs-status { 29 | color: #333; 30 | font-weight: bold 31 | } 32 | 33 | .hljs-number, 34 | .hljs-hexcolor, 35 | .ruby .hljs-constant { 36 | color: #099; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-tag .hljs-value, 41 | .hljs-phpdoc, 42 | .tex .hljs-formula { 43 | color: #d14 44 | } 45 | 46 | .hljs-title, 47 | .hljs-id, 48 | .coffeescript .hljs-params, 49 | .scss .hljs-preprocessor { 50 | color: #900; 51 | font-weight: bold 52 | } 53 | 54 | .javascript .hljs-title, 55 | .lisp .hljs-title, 56 | .clojure .hljs-title, 57 | .hljs-subst { 58 | font-weight: normal 59 | } 60 | 61 | .hljs-class .hljs-title, 62 | .haskell .hljs-type, 63 | .vhdl .hljs-literal, 64 | .tex .hljs-command { 65 | color: #458; 66 | font-weight: bold 67 | } 68 | 69 | .hljs-tag, 70 | .hljs-tag .hljs-title, 71 | .hljs-rules .hljs-property, 72 | .django .hljs-tag .hljs-keyword { 73 | color: #000080; 74 | font-weight: normal 75 | } 76 | 77 | .hljs-attribute, 78 | .hljs-variable, 79 | .lisp .hljs-body { 80 | color: #008080 81 | } 82 | 83 | .hljs-regexp { 84 | color: #009926 85 | } 86 | 87 | .hljs-symbol, 88 | .ruby .hljs-symbol .hljs-string, 89 | .lisp .hljs-keyword, 90 | .tex .hljs-special, 91 | .hljs-prompt { 92 | color: #990073 93 | } 94 | 95 | .hljs-built_in, 96 | .lisp .hljs-title, 97 | .clojure .hljs-built_in { 98 | color: #0086b3 99 | } 100 | 101 | .hljs-preprocessor, 102 | .hljs-pragma, 103 | .hljs-pi, 104 | .hljs-doctype, 105 | .hljs-shebang, 106 | .hljs-cdata { 107 | color: #999; 108 | font-weight: bold 109 | } 110 | 111 | .hljs-deletion { 112 | background: #fdd 113 | } 114 | 115 | .hljs-addition { 116 | background: #dfd 117 | } 118 | 119 | .diff .hljs-change { 120 | background: #0086b3 121 | } 122 | 123 | .hljs-chunk { 124 | color: #aaa 125 | } 126 | -------------------------------------------------------------------------------- /js/side.js: -------------------------------------------------------------------------------- 1 | ;(function($, win, doc) { 2 | 'use strict'; 3 | 4 | var $doc = $(doc), 5 | spring = win.spring, 6 | source = '\ 7 |

<%=$.spring.config.title%>

\ 8 |
<%=#marked($.spring.config.desc)%>
\ 9 |