character 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -1
- data/.rspec +1 -0
- data/README.md +185 -14
- data/Rakefile +8 -1
- data/app/assets/images/character/logo.jpg +0 -0
- data/app/assets/javascripts/character.coffee +134 -0
- data/app/assets/javascripts/character/dashboard/_visitors.coffee +27 -0
- data/app/assets/javascripts/character/dashboard/layout.coffee +156 -0
- data/app/assets/javascripts/character/dashboard/module.coffee +51 -0
- data/app/assets/javascripts/character/generic/details.coffee +233 -0
- data/app/assets/javascripts/character/generic/helpers/compact_object.coffee +7 -0
- data/app/assets/javascripts/character/generic/helpers/data_inputs.coffee +21 -0
- data/app/assets/javascripts/character/generic/helpers/date_select.coffee +45 -0
- data/app/assets/javascripts/character/generic/helpers/editor.coffee +11 -0
- data/app/assets/javascripts/character/generic/helpers/redactor.coffee +38 -0
- data/app/assets/javascripts/character/generic/helpers/reorder.coffee +36 -0
- data/app/assets/javascripts/character/generic/layout.coffee +40 -0
- data/app/assets/javascripts/character/generic/list.coffee +214 -0
- data/app/assets/javascripts/character/generic/model.coffee +135 -0
- data/app/assets/javascripts/character/generic/module.coffee +157 -0
- data/app/assets/javascripts/character/images/module.coffee +148 -0
- data/app/assets/javascripts/character/pages/module.coffee +43 -0
- data/app/assets/javascripts/character/posts/module.coffee +113 -0
- data/app/assets/javascripts/character/settings/_admins.coffee +61 -0
- data/app/assets/javascripts/character/settings/_authors.coffee +56 -0
- data/app/assets/javascripts/character/settings/_categories.coffee +61 -0
- data/app/assets/javascripts/character/settings/_layout.coffee +7 -0
- data/app/assets/javascripts/character/settings/_redirects.coffee +56 -0
- data/app/assets/javascripts/character/settings/_website.coffee +7 -0
- data/app/assets/javascripts/character/settings/details.coffee +16 -0
- data/app/assets/javascripts/character/settings/layout.coffee +46 -0
- data/app/assets/javascripts/character/settings/module.coffee +78 -0
- data/app/assets/stylesheets/character.scss +37 -0
- data/app/assets/stylesheets/character/_admins.scss +30 -0
- data/app/assets/stylesheets/character/_authors.scss +30 -0
- data/app/assets/stylesheets/character/_categories.scss +32 -0
- data/app/assets/stylesheets/character/_dashboard.scss +143 -0
- data/app/assets/stylesheets/character/_posts.scss +93 -0
- data/app/assets/stylesheets/character/_redirects.scss +35 -0
- data/app/assets/stylesheets/character/base.scss +967 -0
- data/app/assets/stylesheets/character/typography.scss +29 -0
- data/app/controllers/character/api_controller.rb +170 -0
- data/app/controllers/character/application_controller.rb +37 -0
- data/app/controllers/character/settings_controller.rb +72 -0
- data/app/controllers/concerns/character/auth_concern.rb +41 -0
- data/app/controllers/concerns/character/instance_concern.rb +31 -0
- data/app/controllers/concerns/character/json_object_concern.rb +32 -0
- data/app/controllers/concerns/character/model_class_concern.rb +28 -0
- data/app/controllers/concerns/character/params_concern.rb +33 -0
- data/app/controllers/concerns/character/templates_concern.rb +32 -0
- data/app/controllers/concerns/not_found.rb +18 -0
- data/app/controllers/concerns/website_settings.rb +18 -0
- data/app/controllers/pages_controller.rb +8 -0
- data/app/controllers/posts_controller.rb +43 -0
- data/app/helpers/character_helper.rb +8 -0
- data/app/helpers/page_helper.rb +67 -0
- data/app/inputs/foundation_string_input.rb +44 -0
- data/app/inputs/foundation_switch_input.rb +35 -0
- data/app/models/character/image.rb +12 -0
- data/app/models/character/page.rb +21 -0
- data/app/models/character/post.rb +32 -12
- data/app/models/character/post_author.rb +22 -0
- data/app/models/character/post_category.rb +21 -0
- data/app/models/character/redirect.rb +15 -0
- data/app/models/character/settings/variable.rb +23 -0
- data/app/models/character/sitemap/sitemap_generator_helper.rb +15 -0
- data/app/models/character/user.rb +29 -0
- data/app/models/concerns/created_ago.rb +12 -0
- data/app/models/concerns/hideable.rb +27 -0
- data/app/models/concerns/orderable.rb +8 -0
- data/app/models/concerns/report.rb +11 -0
- data/app/models/concerns/report_daily.rb +32 -0
- data/app/models/concerns/report_monthly.rb +18 -0
- data/app/models/concerns/report_weekly.rb +19 -0
- data/app/models/concerns/updated_ago.rb +12 -0
- data/app/models/reports/analytics_daily.rb +26 -0
- data/app/models/reports/analytics_monthly.rb +16 -0
- data/app/models/reports/analytics_weekly.rb +16 -0
- data/app/services/google_analytics.rb +43 -0
- data/app/uploaders/character/image_uploader.rb +22 -0
- data/app/uploaders/character/settings/file_uploader.rb +5 -0
- data/app/views/character/character.html.erb +67 -0
- data/app/views/character/generic/form.html.erb +8 -0
- data/app/views/character/pages/form.html.erb +28 -0
- data/app/views/character/posts/form.html.erb +38 -0
- data/app/views/character/settings/admins.html.erb +29 -0
- data/app/views/character/settings/post_authors.html.erb +28 -0
- data/app/views/character/settings/post_categories.html.erb +31 -0
- data/app/views/character/settings/redirects.html.erb +30 -0
- data/app/views/character/settings/settings_group.html.erb +67 -0
- data/app/views/errors/not_found.html.erb +157 -0
- data/app/views/pages/_default.html.erb +3 -0
- data/app/views/pages/_redactor.html.erb +3 -0
- data/app/views/pages/show.html.erb +5 -0
- data/app/views/posts/_post.html.erb +17 -0
- data/app/views/posts/author.html.erb +18 -0
- data/app/views/posts/category.html.erb +18 -0
- data/app/views/posts/index.html.erb +18 -0
- data/app/views/posts/rss.builder +19 -0
- data/app/views/posts/show.html.erb +14 -0
- data/app/views/shared/_google_analytics.html.erb +13 -0
- data/character.gemspec +48 -5
- data/doc/README_old.md +161 -0
- data/doc/generic_app.md +19 -0
- data/doc/img/demo-1.jpg +0 -0
- data/doc/img/demo-2.jpg +0 -0
- data/doc/img/demo-3.jpg +0 -0
- data/doc/img/demo-4.jpg +0 -0
- data/doc/img/demo-5.jpg +0 -0
- data/doc/instances.md +39 -0
- data/doc/settings.md +1 -0
- data/lib/character.rb +29 -1
- data/lib/character/engine.rb +33 -1
- data/lib/character/generators/bootstrap_generator.rb +51 -0
- data/lib/character/instance.rb +59 -0
- data/lib/character/routing.rb +42 -5
- data/lib/character/settings.rb +101 -0
- data/lib/character/templates/admin.coffee +15 -0
- data/lib/character/templates/admin.scss +3 -0
- data/lib/character/templates/application.html.erb +44 -0
- data/lib/character/templates/application.scss +12 -0
- data/lib/character/templates/assets.rb +1 -0
- data/lib/character/templates/initializer.rb +5 -0
- data/lib/character/templates/settings.scss +11 -0
- data/lib/character/templates/settings.yml +67 -0
- data/lib/character/templates/typography.scss +13 -0
- data/lib/character/version.rb +2 -2
- data/lib/mongoid/carrierwave_serialization_patch.rb +9 -0
- data/lib/tasks/analytics.rake +52 -0
- data/test/config/application.rb +65 -0
- data/test/config/mongoid.yml +12 -0
- data/test/config/secrets.yml +22 -0
- data/test/controllers/character/api_controller_test.rb +94 -0
- data/test/factories/product_factory.rb +5 -0
- data/test/lib/character/engine_test.rb +33 -0
- data/test/lib/character/routing_test.rb +31 -0
- data/test/test_helper.rb +48 -0
- data/vendor/assets/javascripts/backbone.js +944 -794
- data/vendor/assets/javascripts/jquery.fileupload.js +1426 -0
- data/vendor/assets/javascripts/jquery.form.js +1278 -0
- data/vendor/assets/javascripts/jquery.iframe-transport.js +214 -0
- data/vendor/assets/javascripts/raphael.js +8117 -0
- data/vendor/assets/javascripts/raphael.morris.js +1885 -0
- data/vendor/assets/javascripts/underscore.inflection.js +177 -0
- data/vendor/assets/javascripts/underscore.string.js +1 -1
- data/vendor/assets/stylesheets/csspinner.css +361 -0
- data/vendor/assets/stylesheets/normalize.css +423 -0
- metadata +499 -49
- data/app/controllers/character/posts_controller.rb +0 -27
- data/lib/generators/character/install_generator.rb +0 -42
- data/lib/generators/character/templates/README +0 -1
- data/lib/generators/character/templates/admin/character.rb +0 -3
- data/vendor/assets/fonts/general_foundicons.eot +0 -0
- data/vendor/assets/fonts/general_foundicons.svg +0 -15
- data/vendor/assets/fonts/general_foundicons.ttf +0 -0
- data/vendor/assets/fonts/general_foundicons.woff +0 -0
- data/vendor/assets/javascripts/character/index.js.coffee +0 -53
- data/vendor/assets/javascripts/character/models/post.js.coffee +0 -39
- data/vendor/assets/javascripts/character/views/app.js.coffee +0 -81
- data/vendor/assets/javascripts/character/views/editor.js.coffee +0 -231
- data/vendor/assets/javascripts/character/views/editor_settings.js.coffee +0 -44
- data/vendor/assets/javascripts/character/views/index.js.coffee +0 -116
- data/vendor/assets/javascripts/character/views/preview.js.coffee +0 -49
- data/vendor/assets/javascripts/jquery.smartresize.js +0 -30
- data/vendor/assets/javascripts/lodash.js +0 -4258
- data/vendor/assets/javascripts/showdown.js +0 -62
- data/vendor/assets/stylesheets/character/_base.css.scss +0 -84
- data/vendor/assets/stylesheets/character/_icons.css.scss.erb +0 -96
- data/vendor/assets/stylesheets/character/_view_editor.css.scss +0 -115
- data/vendor/assets/stylesheets/character/_view_index.css.scss +0 -73
- data/vendor/assets/stylesheets/character/_view_preview.css.scss +0 -49
- data/vendor/assets/stylesheets/character/index.css.scss +0 -32
@@ -1,27 +0,0 @@
|
|
1
|
-
class Character::PostsController < ApplicationController
|
2
|
-
before_filter :authenticate_admin_user!
|
3
|
-
|
4
|
-
def index
|
5
|
-
@posts = []
|
6
|
-
@posts += Character::Post.drafts.to_a
|
7
|
-
@posts += Character::Post.published.to_a
|
8
|
-
render json: @posts
|
9
|
-
end
|
10
|
-
|
11
|
-
def create
|
12
|
-
@post = Character::Post.create params[:post]
|
13
|
-
render json: @post
|
14
|
-
end
|
15
|
-
|
16
|
-
def update
|
17
|
-
@post = Character::Post.find(params[:id])
|
18
|
-
@post.update_attributes params[:post]
|
19
|
-
render json: @post
|
20
|
-
end
|
21
|
-
|
22
|
-
def destroy
|
23
|
-
@post = Character::Post.find(params[:id])
|
24
|
-
@post.destroy
|
25
|
-
render json: 'ok'
|
26
|
-
end
|
27
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Character
|
2
|
-
module Generators
|
3
|
-
class InstallGenerator < Rails::Generators::Base
|
4
|
-
desc << "Description:\n Copies Chatacter source files to your application's app directory, adds routes and missing gems."
|
5
|
-
|
6
|
-
source_root File.expand_path('../templates', __FILE__)
|
7
|
-
|
8
|
-
def copy_files
|
9
|
-
puts "Installing active admin page for Character:"
|
10
|
-
copy_file "admin/character.rb", "app/admin/character.rb"
|
11
|
-
end
|
12
|
-
|
13
|
-
def add_assets
|
14
|
-
missing_file_message = "It doesn't look like you've installed activeadmin: active_admin.css.scss is missing.\nPlease run: rails g active_admin:install - install it and try again."
|
15
|
-
|
16
|
-
if File.exist?('app/assets/javascripts/active_admin.js')
|
17
|
-
partial1 = "//= require character\n\n"
|
18
|
-
partial2 = "$(function(){ if ($('.admin_character').length > 0) window.initialize_character('http://blog-url.com/'); });\n\n"
|
19
|
-
|
20
|
-
insert_into_file "app/assets/javascripts/active_admin.js", partial1 + partial2, :after => "base\n"
|
21
|
-
else
|
22
|
-
puts missing_file_message
|
23
|
-
end
|
24
|
-
|
25
|
-
if File.exist?('app/assets/stylesheets/active_admin.css.scss')
|
26
|
-
insert_into_file "app/assets/stylesheets/active_admin.css.scss",
|
27
|
-
"@import 'character';\n", :after => "base\";\n"
|
28
|
-
else
|
29
|
-
puts missing_file_message
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def mount_engine
|
34
|
-
route "mount_character()"
|
35
|
-
end
|
36
|
-
|
37
|
-
def show_congrats
|
38
|
-
readme("README")
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
Character
|
Binary file
|
@@ -1,15 +0,0 @@
|
|
1
|
-
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" > <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
|
2
|
-
<defs >
|
3
|
-
<font id="generalfoundicons" horiz-adv-x="955" ><font-face
|
4
|
-
font-family="General Foundicons"
|
5
|
-
units-per-em="1000"
|
6
|
-
panose-1="0 0 0 0 0 0 0 0 0 0"
|
7
|
-
ascent="1000"
|
8
|
-
descent="0"
|
9
|
-
alphabetic="0" />
|
10
|
-
<missing-glyph horiz-adv-x="250" />
|
11
|
-
<glyph unicode=" " glyph-name="space" horiz-adv-x="250" />
|
12
|
-
<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="1000" />
|
13
|
-
</font>
|
14
|
-
</defs>
|
15
|
-
</svg>
|
Binary file
|
Binary file
|
@@ -1,53 +0,0 @@
|
|
1
|
-
#= require ../lodash
|
2
|
-
#= require ../underscore.string
|
3
|
-
#= require ../backbone
|
4
|
-
#= require ../showdown
|
5
|
-
#= require ../jquery.smartresize
|
6
|
-
|
7
|
-
#= require_tree ./models
|
8
|
-
#= require_tree ./views
|
9
|
-
#= require_tree ./
|
10
|
-
|
11
|
-
|
12
|
-
window.set_routes = ->
|
13
|
-
Router = Backbone.Router.extend
|
14
|
-
routes:
|
15
|
-
'new': 'newPost'
|
16
|
-
'edit/:id': 'editPost'
|
17
|
-
'preview/:id': 'showPostPreview'
|
18
|
-
'': 'showIndex'
|
19
|
-
|
20
|
-
router = new Router
|
21
|
-
|
22
|
-
router.on 'route:newPost', ->
|
23
|
-
window.app.show_editor()
|
24
|
-
|
25
|
-
router.on 'route:editPost', (id) ->
|
26
|
-
window.app.show_editor(id)
|
27
|
-
|
28
|
-
router.on 'route:showPostPreview', (id) ->
|
29
|
-
window.app.show_preview(id)
|
30
|
-
|
31
|
-
router.on 'route:showIndex', (id) ->
|
32
|
-
if window.app.preview_view
|
33
|
-
window.app.close_preview()
|
34
|
-
else
|
35
|
-
window.app.show_index()
|
36
|
-
|
37
|
-
window.router = router
|
38
|
-
|
39
|
-
# Start Backbone history a necessary step for bookmarkable URL's
|
40
|
-
Backbone.history.start()
|
41
|
-
|
42
|
-
|
43
|
-
window.initialize_character = (blog_url = 'http://this-is-blog.com/', app_container = '#wrapper') ->
|
44
|
-
window.posts = new Posts()
|
45
|
-
|
46
|
-
window.posts.fetch success: ->
|
47
|
-
window.app = new AppView(blog_url, app_container)
|
48
|
-
window.app.show_index()
|
49
|
-
|
50
|
-
window.set_routes()
|
51
|
-
|
52
|
-
|
53
|
-
|
@@ -1,39 +0,0 @@
|
|
1
|
-
class Post extends Backbone.Model
|
2
|
-
#id
|
3
|
-
#title
|
4
|
-
#category
|
5
|
-
#featured_image
|
6
|
-
#html
|
7
|
-
#md
|
8
|
-
#date
|
9
|
-
#views
|
10
|
-
#published
|
11
|
-
|
12
|
-
idAttribute: '_id'
|
13
|
-
|
14
|
-
|
15
|
-
date_formatted: ->
|
16
|
-
date = @get('date')
|
17
|
-
if date then date.replace(/-/g, '/') else "Date Not Set"
|
18
|
-
|
19
|
-
|
20
|
-
featured_image: ->
|
21
|
-
@get('featured_image_url')
|
22
|
-
|
23
|
-
|
24
|
-
state: ->
|
25
|
-
if @get('published')
|
26
|
-
"Published"
|
27
|
-
else "Draft"
|
28
|
-
|
29
|
-
|
30
|
-
@slugify: (text) ->
|
31
|
-
_.string.slugify(text)
|
32
|
-
|
33
|
-
|
34
|
-
class Posts extends Backbone.Collection
|
35
|
-
model: Post
|
36
|
-
url: '/admin/character/posts'
|
37
|
-
|
38
|
-
window.Posts = Posts
|
39
|
-
window.Post = Post
|
@@ -1,81 +0,0 @@
|
|
1
|
-
############################
|
2
|
-
### CHARACTER :: AppView ###
|
3
|
-
############################
|
4
|
-
|
5
|
-
class AppView extends Backbone.View
|
6
|
-
|
7
|
-
initialize: (@blog_url, @el) ->
|
8
|
-
@render()
|
9
|
-
window.index_scroll_y = 0
|
10
|
-
@blog_url ||= 'http://default-blog-url.com/'
|
11
|
-
|
12
|
-
|
13
|
-
render: ->
|
14
|
-
html = """<div id='main'></div>"""
|
15
|
-
$(@el).append html
|
16
|
-
|
17
|
-
|
18
|
-
find_post: (id) ->
|
19
|
-
window.posts.get(id)
|
20
|
-
|
21
|
-
|
22
|
-
clear_view: ->
|
23
|
-
(@index_view.remove() ; delete @index_view) if @index_view
|
24
|
-
(@preview_view.remove() ; delete @preview_view) if @preview_view
|
25
|
-
(@editor_view.remove() ; delete @editor_view) if @editor_view
|
26
|
-
|
27
|
-
|
28
|
-
show_index: ->
|
29
|
-
@clear_view()
|
30
|
-
@index_view = new IndexView()
|
31
|
-
|
32
|
-
|
33
|
-
show_preview: (post_id) ->
|
34
|
-
if @editor_view
|
35
|
-
@clear_view()
|
36
|
-
@show_index()
|
37
|
-
|
38
|
-
@index_view.set_active(post_id)
|
39
|
-
|
40
|
-
if not @preview_view
|
41
|
-
@index_view.lock()
|
42
|
-
|
43
|
-
# render preview
|
44
|
-
@preview_view.remove() if @preview_view
|
45
|
-
|
46
|
-
post = @find_post(post_id)
|
47
|
-
@preview_view = new PostPreviewView model: post
|
48
|
-
|
49
|
-
html = @preview_view.render().el
|
50
|
-
|
51
|
-
$('#main').append(html)
|
52
|
-
|
53
|
-
window.scroll(0, 0)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
close_preview: ->
|
58
|
-
@index_view.unlock()
|
59
|
-
|
60
|
-
# hide preview
|
61
|
-
if @preview_view
|
62
|
-
@preview_view.remove()
|
63
|
-
delete @preview_view
|
64
|
-
|
65
|
-
@index_view.unset_active()
|
66
|
-
window.index_scroll_y = 0
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
show_editor: (post_id) ->
|
71
|
-
@clear_view()
|
72
|
-
|
73
|
-
post = if post_id then @find_post(post_id) else null
|
74
|
-
|
75
|
-
@editor_view = new EditorView model: post
|
76
|
-
|
77
|
-
|
78
|
-
window.AppView = AppView
|
79
|
-
|
80
|
-
|
81
|
-
|
@@ -1,231 +0,0 @@
|
|
1
|
-
###############################
|
2
|
-
### CHARACTER :: EditorView ###
|
3
|
-
###############################
|
4
|
-
|
5
|
-
# Code is partly taken from:
|
6
|
-
# - http://www.showdown.im/showdown/example/showdown-gui.js
|
7
|
-
|
8
|
-
class EditorView extends Backbone.View
|
9
|
-
tagName: 'div'
|
10
|
-
className: 'editor'
|
11
|
-
|
12
|
-
|
13
|
-
initialize: ->
|
14
|
-
html = @render().el
|
15
|
-
$('#main').append(html)
|
16
|
-
|
17
|
-
@settings = new EditorSettingsView model: @model
|
18
|
-
|
19
|
-
@converter = new Showdown.converter()
|
20
|
-
@last_text = null
|
21
|
-
@title = document.getElementById('title')
|
22
|
-
@update_permalink()
|
23
|
-
|
24
|
-
@slug = document.getElementById('slug')
|
25
|
-
@markdown = document.getElementById('markdown')
|
26
|
-
@html = document.getElementById('html')
|
27
|
-
@max_delay = 3000
|
28
|
-
|
29
|
-
@resize_panels()
|
30
|
-
@typing_events()
|
31
|
-
@convert_text()
|
32
|
-
|
33
|
-
|
34
|
-
update_or_create_post: (extra_attributes, callback) ->
|
35
|
-
attributes =
|
36
|
-
title: $(@title).val()
|
37
|
-
md: $(@markdown).val()
|
38
|
-
html: @html.innerHTML
|
39
|
-
slug: @slug.innerHTML
|
40
|
-
date: @settings.date()
|
41
|
-
|
42
|
-
_.extend attributes, extra_attributes
|
43
|
-
|
44
|
-
if @model
|
45
|
-
@model.save(attributes, {success: callback})
|
46
|
-
else
|
47
|
-
window.posts.create(attributes, {wait: true, success: callback})
|
48
|
-
|
49
|
-
|
50
|
-
#if @model.isNew()
|
51
|
-
# @model.set
|
52
|
-
# id: @model.cid
|
53
|
-
# views: 0
|
54
|
-
# @model.save()
|
55
|
-
# window.posts.add(@model, {at: 0})
|
56
|
-
|
57
|
-
|
58
|
-
save_draft: ->
|
59
|
-
@update_or_create_post {published: false}, =>
|
60
|
-
@back_to_index()
|
61
|
-
|
62
|
-
|
63
|
-
publish: ->
|
64
|
-
@update_or_create_post {published: true}, =>
|
65
|
-
@back_to_index()
|
66
|
-
|
67
|
-
|
68
|
-
back_to_index: ->
|
69
|
-
path = if @model then "#/preview/#{@model.id}" else '#/'
|
70
|
-
router.navigate(path, {trigger: true})
|
71
|
-
|
72
|
-
|
73
|
-
events:
|
74
|
-
'click .save-draft': 'save_draft'
|
75
|
-
'click .publish': 'publish'
|
76
|
-
'click .cancel': 'back_to_index'
|
77
|
-
|
78
|
-
|
79
|
-
update_word_counter: ->
|
80
|
-
counter = 0
|
81
|
-
md_text = $(@markdown).val()
|
82
|
-
if md_text.length > 0
|
83
|
-
counter = md_text.match(/[^\s]+/g).length
|
84
|
-
$(document.getElementById('word_counter')).html "#{counter} words"
|
85
|
-
|
86
|
-
|
87
|
-
update_permalink: ->
|
88
|
-
blog_url = window.app.blog_url
|
89
|
-
slug = Post.slugify($(@title).val())
|
90
|
-
html = """<strong>Permalink:</strong> #{blog_url}<strong id='slug'>#{slug}</strong>"""
|
91
|
-
$('#permalink').html html
|
92
|
-
|
93
|
-
|
94
|
-
render: ->
|
95
|
-
post = if @model then @model.toJSON() else {title: 'Post Title', md: 'Post Text'}
|
96
|
-
|
97
|
-
html = """<header>
|
98
|
-
<div class='title'>
|
99
|
-
<input type='text' placeholder='Title' value='#{post.title}' id='title'/>
|
100
|
-
</div>
|
101
|
-
<div class='permalink' id='permalink'>
|
102
|
-
</div>
|
103
|
-
</header>
|
104
|
-
|
105
|
-
<div class='chr-panel left index fixed'>
|
106
|
-
<section class='container'>
|
107
|
-
<header>
|
108
|
-
<span class='title'>Markdown</span>
|
109
|
-
<span class='buttons'>
|
110
|
-
<a href='#' title='Markdown syntax' class='foundicon-help'></a>
|
111
|
-
</span>
|
112
|
-
</header>
|
113
|
-
<div>
|
114
|
-
<textarea id='markdown'>#{post.md}</textarea>
|
115
|
-
</div>
|
116
|
-
</section>
|
117
|
-
</div>
|
118
|
-
|
119
|
-
<div class='chr-panel right preview fixed'>
|
120
|
-
<section class='container'>
|
121
|
-
<header>
|
122
|
-
<span class='title'>Preview</span>
|
123
|
-
<span class='info' id='word_counter'>549 words</span>
|
124
|
-
</header>
|
125
|
-
|
126
|
-
<article>
|
127
|
-
<section class='content' id='html'></section>
|
128
|
-
</article>
|
129
|
-
</section>
|
130
|
-
</div>
|
131
|
-
|
132
|
-
<footer>
|
133
|
-
<button class='cancel'>Cancel</button>
|
134
|
-
<button class='publish'>Publish</button>
|
135
|
-
<button class='save-draft'>Save Draft</button>
|
136
|
-
</footer>"""
|
137
|
-
$(this.el).html html
|
138
|
-
return this
|
139
|
-
|
140
|
-
|
141
|
-
on_input: (callback) ->
|
142
|
-
# In "delayed" mode, we do the conversion at pauses in input.
|
143
|
-
# The pause is equal to the last runtime, so that slow
|
144
|
-
# updates happen less frequently.
|
145
|
-
#
|
146
|
-
# Use a timer to schedule updates. Each keystroke
|
147
|
-
# resets the timer.
|
148
|
-
|
149
|
-
# if we already have convertText scheduled, cancel it
|
150
|
-
if convert_text_timer
|
151
|
-
window.clearTimeout(convert_text_timer)
|
152
|
-
convert_text_timer = null
|
153
|
-
|
154
|
-
time_until_convert_text = 0
|
155
|
-
|
156
|
-
if time_until_convert_text > @max_delay
|
157
|
-
time_until_convert_text = @max_delay
|
158
|
-
|
159
|
-
# Schedule @convert_text().
|
160
|
-
# Even if we're updating every keystroke, use a timer at 0.
|
161
|
-
# This gives the browser time to handle other events.
|
162
|
-
convert_text_timer = window.setTimeout(callback, time_until_convert_text)
|
163
|
-
|
164
|
-
|
165
|
-
typing_events: ->
|
166
|
-
# First, try registering for keyup events
|
167
|
-
# (There's no harm in calling onInput() repeatedly)
|
168
|
-
@markdown.onkeyup = => @on_input(@convert_text)
|
169
|
-
@title.onkeyup = => @on_input(@update_permalink)
|
170
|
-
|
171
|
-
# In case we can't capture paste events, poll for them
|
172
|
-
polling_fallback = window.setInterval ( => @on_input() if not @markdown.value == @last_text ), 1000
|
173
|
-
|
174
|
-
# Try registering for paste events
|
175
|
-
@markdown.onpaste = =>
|
176
|
-
# It worked! Cancel paste polling.
|
177
|
-
if polling_fallback
|
178
|
-
window.clearInterval(polling_fallback)
|
179
|
-
polling_fallback = null
|
180
|
-
@on_input()
|
181
|
-
|
182
|
-
# Try registering for input events (the best solution)
|
183
|
-
if @markdown.addEventListener
|
184
|
-
# Let's assume input also fires on paste.
|
185
|
-
# No need to cancel our keyup handlers;
|
186
|
-
# they're basically free.
|
187
|
-
@markdown.addEventListener('input', @markdown.onpaste, false)
|
188
|
-
|
189
|
-
@markdown.focus()
|
190
|
-
|
191
|
-
|
192
|
-
convert_text: =>
|
193
|
-
text = @markdown.value
|
194
|
-
|
195
|
-
return if text and text == @last_text
|
196
|
-
|
197
|
-
@last_text = text
|
198
|
-
|
199
|
-
# do the conversion
|
200
|
-
@html.innerHTML = @converter.makeHtml(text)
|
201
|
-
@update_word_counter()
|
202
|
-
|
203
|
-
|
204
|
-
resize_panels: ->
|
205
|
-
markdown = $(@markdown)
|
206
|
-
html = $(@html).parent()
|
207
|
-
window_height = $(window).height()
|
208
|
-
footer_height = $('footer').outerHeight()
|
209
|
-
|
210
|
-
markdown.css 'height', window_height - markdown.offset().top - footer_height
|
211
|
-
html.css 'height', window_height - html.offset().top - footer_height
|
212
|
-
|
213
|
-
$(window).smartresize =>
|
214
|
-
@resize_panels()
|
215
|
-
|
216
|
-
|
217
|
-
destroy = ->
|
218
|
-
# clear smartresize event
|
219
|
-
@markdown.onkeyup = null
|
220
|
-
@title.onkeyup = null
|
221
|
-
|
222
|
-
|
223
|
-
window.EditorView = EditorView
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|