railswiki 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +185 -0
- data/Rakefile +24 -0
- data/app/assets/config/railswiki_manifest.js +2 -0
- data/app/assets/javascripts/railswiki/application.js +13 -0
- data/app/assets/javascripts/railswiki/histories.js +2 -0
- data/app/assets/javascripts/railswiki/invites.js +2 -0
- data/app/assets/javascripts/railswiki/pages.js +2 -0
- data/app/assets/javascripts/railswiki/sessions.js +2 -0
- data/app/assets/javascripts/railswiki/uploaded_files.js +2 -0
- data/app/assets/javascripts/railswiki/users.js +2 -0
- data/app/assets/stylesheets/railswiki/application.css +15 -0
- data/app/assets/stylesheets/railswiki/histories.css +4 -0
- data/app/assets/stylesheets/railswiki/invites.css +4 -0
- data/app/assets/stylesheets/railswiki/pages.scss +55 -0
- data/app/assets/stylesheets/railswiki/sessions.css +4 -0
- data/app/assets/stylesheets/railswiki/uploaded_files.scss +54 -0
- data/app/assets/stylesheets/railswiki/users.css +4 -0
- data/app/controllers/railswiki/application_controller.rb +126 -0
- data/app/controllers/railswiki/histories_controller.rb +48 -0
- data/app/controllers/railswiki/invites_controller.rb +61 -0
- data/app/controllers/railswiki/pages_controller.rb +141 -0
- data/app/controllers/railswiki/sessions_controller.rb +75 -0
- data/app/controllers/railswiki/uploaded_files_controller.rb +100 -0
- data/app/controllers/railswiki/users_controller.rb +55 -0
- data/app/helpers/railswiki/application_helper.rb +26 -0
- data/app/helpers/railswiki/histories_helper.rb +4 -0
- data/app/helpers/railswiki/invites_helper.rb +4 -0
- data/app/helpers/railswiki/pages_helper.rb +76 -0
- data/app/helpers/railswiki/sessions_helper.rb +4 -0
- data/app/helpers/railswiki/title_helper.rb +7 -0
- data/app/helpers/railswiki/uploaded_files_helper.rb +4 -0
- data/app/helpers/railswiki/users_helper.rb +4 -0
- data/app/helpers/railswiki/wiki_helper.rb +189 -0
- data/app/jobs/railswiki/application_job.rb +4 -0
- data/app/mailers/railswiki/application_mailer.rb +6 -0
- data/app/models/railswiki/application_record.rb +5 -0
- data/app/models/railswiki/history.rb +14 -0
- data/app/models/railswiki/invite.rb +20 -0
- data/app/models/railswiki/page.rb +56 -0
- data/app/models/railswiki/uploaded_file.rb +32 -0
- data/app/models/railswiki/user.rb +27 -0
- data/app/uploaders/railswiki/file_uploader.rb +56 -0
- data/app/views/layouts/railswiki/application.html.erb +25 -0
- data/app/views/railswiki/histories/index.html.erb +33 -0
- data/app/views/railswiki/histories/show.html.erb +17 -0
- data/app/views/railswiki/invites/_form.html.erb +38 -0
- data/app/views/railswiki/invites/index.html.erb +39 -0
- data/app/views/railswiki/invites/new.html.erb +7 -0
- data/app/views/railswiki/invites/show.html.erb +34 -0
- data/app/views/railswiki/pages/_form.html.erb +144 -0
- data/app/views/railswiki/pages/edit.html.erb +8 -0
- data/app/views/railswiki/pages/history.html.erb +11 -0
- data/app/views/railswiki/pages/index.html.erb +72 -0
- data/app/views/railswiki/pages/new.html.erb +7 -0
- data/app/views/railswiki/pages/show.html.erb +36 -0
- data/app/views/railswiki/sessions/no_invite.erb +7 -0
- data/app/views/railswiki/sessions/not_authorized.html.erb +12 -0
- data/app/views/railswiki/uploaded_files/_form.html.erb +31 -0
- data/app/views/railswiki/uploaded_files/_inline.html.erb +5 -0
- data/app/views/railswiki/uploaded_files/edit.html.erb +8 -0
- data/app/views/railswiki/uploaded_files/file_dialog.html.erb +11 -0
- data/app/views/railswiki/uploaded_files/image_dialog.html.erb +11 -0
- data/app/views/railswiki/uploaded_files/index.html.erb +36 -0
- data/app/views/railswiki/uploaded_files/new.html.erb +7 -0
- data/app/views/railswiki/uploaded_files/show.html.erb +29 -0
- data/app/views/railswiki/users/_form.html.erb +29 -0
- data/app/views/railswiki/users/edit.html.erb +8 -0
- data/app/views/railswiki/users/index.html.erb +37 -0
- data/app/views/railswiki/users/show.html.erb +59 -0
- data/app/views/shared/_formatting.md.erb +29 -0
- data/app/views/shared/_histories.html.erb +21 -0
- data/app/views/shared/_layout.html.erb +17 -0
- data/app/views/shared/_menu.html.erb +15 -0
- data/app/views/shared/_meta.html.erb +1 -0
- data/app/views/shared/_notices.html.erb +3 -0
- data/app/views/shared/_roles.html.erb +12 -0
- data/app/views/shared/_search.md.erb +5 -0
- data/config/initializers/carrierwave.rb +6 -0
- data/config/initializers/omniauth.rb +16 -0
- data/config/initializers/session_store.rb +1 -0
- data/config/routes.rb +25 -0
- data/db/migrate/20170420000841_create_railswiki_pages.rb +10 -0
- data/db/migrate/20170420010111_add_sessions_table.rb +12 -0
- data/db/migrate/20170420010147_create_railswiki_users.rb +14 -0
- data/db/migrate/20170420021039_add_lowercase_title_to_page.rb +5 -0
- data/db/migrate/20170420021840_create_railswiki_histories.rb +11 -0
- data/db/migrate/20170420235420_add_email_and_image_to_user.rb +8 -0
- data/db/migrate/20170421000333_add_last_login_to_user.rb +5 -0
- data/db/migrate/20170421010945_add_role_to_user.rb +7 -0
- data/db/migrate/20170421020932_create_railswiki_uploaded_files.rb +10 -0
- data/db/migrate/20170421030140_add_title_to_uploaded_file.rb +5 -0
- data/db/migrate/20170517224700_create_railswiki_invites.rb +12 -0
- data/db/migrate/20170517234452_add_role_to_invite.rb +5 -0
- data/db/migrate/20170622033540_set_all_mysql_tables_to_utf8.rb +54 -0
- data/lib/railswiki.rb +5 -0
- data/lib/railswiki/engine.rb +14 -0
- data/lib/railswiki/version.rb +3 -0
- data/lib/tasks/railswiki_tasks.rake +4 -0
- metadata +255 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require "email_validator"
|
|
2
|
+
|
|
3
|
+
module Railswiki
|
|
4
|
+
class User < ApplicationRecord
|
|
5
|
+
ROLE_ADMIN = "admin"
|
|
6
|
+
ROLE_EDITOR = "editor"
|
|
7
|
+
ROLE_DEFAULT = "user"
|
|
8
|
+
|
|
9
|
+
AVAILABLE_ROLES = [ROLE_ADMIN, ROLE_EDITOR, ROLE_DEFAULT]
|
|
10
|
+
|
|
11
|
+
has_many :histories, dependent: :nullify, foreign_key: "author_id"
|
|
12
|
+
has_many :uploaded_files, dependent: :nullify
|
|
13
|
+
has_many :invites, dependent: :nullify, foreign_key: "inviting_user_id"
|
|
14
|
+
has_one :invite, dependent: :destroy, foreign_key: "invited_user_id"
|
|
15
|
+
|
|
16
|
+
validates :provider, presence: true
|
|
17
|
+
validates :email, presence: true, uniqueness: true, email: true
|
|
18
|
+
validates :role, presence: true, inclusion: { in: AVAILABLE_ROLES }
|
|
19
|
+
|
|
20
|
+
def expose_json
|
|
21
|
+
{
|
|
22
|
+
id: id,
|
|
23
|
+
name: name,
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require_dependency "carrierwave"
|
|
2
|
+
|
|
3
|
+
module Railswiki
|
|
4
|
+
class FileUploader < CarrierWave::Uploader::Base
|
|
5
|
+
|
|
6
|
+
# Include RMagick or MiniMagick support:
|
|
7
|
+
# include CarrierWave::RMagick
|
|
8
|
+
# include CarrierWave::MiniMagick
|
|
9
|
+
|
|
10
|
+
# Choose what kind of storage to use for this uploader:
|
|
11
|
+
storage :file
|
|
12
|
+
# storage :fog
|
|
13
|
+
|
|
14
|
+
# Override the directory where uploaded files will be stored.
|
|
15
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
|
16
|
+
def store_dir
|
|
17
|
+
"public/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def cache_dir
|
|
21
|
+
Rails.root.join 'tmp/uploads/cache'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
|
25
|
+
# def default_url
|
|
26
|
+
# # For Rails 3.1+ asset pipeline compatibility:
|
|
27
|
+
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
|
28
|
+
#
|
|
29
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
|
30
|
+
# end
|
|
31
|
+
|
|
32
|
+
# Process files as they are uploaded:
|
|
33
|
+
# process scale: [200, 300]
|
|
34
|
+
#
|
|
35
|
+
# def scale(width, height)
|
|
36
|
+
# # do something
|
|
37
|
+
# end
|
|
38
|
+
|
|
39
|
+
# Create different versions of your uploaded files:
|
|
40
|
+
# version :thumb do
|
|
41
|
+
# process resize_to_fit: [50, 50]
|
|
42
|
+
# end
|
|
43
|
+
|
|
44
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
|
45
|
+
# For images you might use something like this:
|
|
46
|
+
# def extension_whitelist
|
|
47
|
+
# %w(jpg jpeg gif png)
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
# Override the filename of the uploaded files:
|
|
51
|
+
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
|
52
|
+
# def filename
|
|
53
|
+
# "file#{File.extname(super)}" if super
|
|
54
|
+
# end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= content_for?(:title) ? yield(:title) : 'Railswiki' %></title>
|
|
5
|
+
<%= stylesheet_link_tag "railswiki/application", media: "all" %>
|
|
6
|
+
<%= javascript_include_tag "railswiki/application" %>
|
|
7
|
+
|
|
8
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
|
9
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
|
|
10
|
+
|
|
11
|
+
<%= javascript_pack_tag "application" %>
|
|
12
|
+
<%= stylesheet_pack_tag "application" %>
|
|
13
|
+
|
|
14
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
15
|
+
|
|
16
|
+
<%= csrf_meta_tags %>
|
|
17
|
+
|
|
18
|
+
<%= render partial: "shared/meta" %>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
|
|
22
|
+
<%= render partial: "shared/layout" %>
|
|
23
|
+
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<% title ["Recent changes"] %>
|
|
2
|
+
|
|
3
|
+
<div class="meta-content">
|
|
4
|
+
<h1>Histories</h1>
|
|
5
|
+
|
|
6
|
+
<table class="list-table">
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<th>Title</th>
|
|
10
|
+
<th>Latest version</th>
|
|
11
|
+
<% if user_can?(:see_page_author) %>
|
|
12
|
+
<th>Author</th>
|
|
13
|
+
<% end %>
|
|
14
|
+
<th colspan="3"></th>
|
|
15
|
+
</tr>
|
|
16
|
+
</thead>
|
|
17
|
+
|
|
18
|
+
<tbody>
|
|
19
|
+
<% @histories.order(created_at: :desc).limit(100).each do |history| %>
|
|
20
|
+
<tr>
|
|
21
|
+
<td><%= link_to history.page.title, wiki_path(history.page) %></td>
|
|
22
|
+
<td><%= time_ago_in_words(history.created_at) %> ago</td>
|
|
23
|
+
<% if user_can?(:see_page_author) %>
|
|
24
|
+
<td><%= user_link history.author %></td>
|
|
25
|
+
<% end %>
|
|
26
|
+
<td><%= link_to "json", history_path(history, format: :json) %></td>
|
|
27
|
+
<td><%= link_to 'Destroy', history, method: :delete, data: { confirm: 'Are you sure?' } if user_can?(:delete_history) %></td>
|
|
28
|
+
</tr>
|
|
29
|
+
<% end %>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
|
|
33
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<% title ["#{@history.page.title} (as at #{@history.created_at})"] %>
|
|
2
|
+
|
|
3
|
+
<h1>
|
|
4
|
+
<%= link_to @history.page.title, wiki_path(@history.page) %>
|
|
5
|
+
<small><%= link_to ".json", history_path(@history, format: :json) %></small>
|
|
6
|
+
as at <%= time_ago @history.created_at %></h1>
|
|
7
|
+
|
|
8
|
+
<div class="wiki-content">
|
|
9
|
+
<%= raw markdown.render @history.body %>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<p>
|
|
13
|
+
<strong>Edited by</strong>
|
|
14
|
+
<%= link_to @history.author.name, @history.author %>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<%= link_to 'Back', histories_path %>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<%= form_for(invite) do |f| %>
|
|
2
|
+
<% if invite.errors.any? %>
|
|
3
|
+
<div id="error_explanation">
|
|
4
|
+
<h2><%= pluralize(invite.errors.count, "error") %> prohibited this invite from being saved:</h2>
|
|
5
|
+
|
|
6
|
+
<ul>
|
|
7
|
+
<% invite.errors.full_messages.each do |message| %>
|
|
8
|
+
<li><%= message %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<div class="field">
|
|
15
|
+
<%= f.label :email %>
|
|
16
|
+
<%= f.text_field :email %>
|
|
17
|
+
|
|
18
|
+
<small class="tip">
|
|
19
|
+
Invited users need to sign in using the same Google Account
|
|
20
|
+
registered to this e-mail address.
|
|
21
|
+
</small>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="field">
|
|
25
|
+
<%= f.label :inviting_user %>
|
|
26
|
+
<%= user_link invite.inviting_user %>
|
|
27
|
+
|
|
28
|
+
<small class="tip">
|
|
29
|
+
That's you!
|
|
30
|
+
</small>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<%= render("shared/roles", form: f) %>
|
|
34
|
+
|
|
35
|
+
<div class="actions">
|
|
36
|
+
<%= f.submit %>
|
|
37
|
+
</div>
|
|
38
|
+
<% end %>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<% title ["Invites"] %>
|
|
2
|
+
|
|
3
|
+
<div class="meta-content">
|
|
4
|
+
<h1>Invites</h1>
|
|
5
|
+
|
|
6
|
+
<table class="list-table">
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<th>Email</th>
|
|
10
|
+
<th>Invited By</th>
|
|
11
|
+
<th>Invited User</th>
|
|
12
|
+
<th>Invited At</th>
|
|
13
|
+
<th>Accepted At</th>
|
|
14
|
+
<th colspan="2"></th>
|
|
15
|
+
</tr>
|
|
16
|
+
</thead>
|
|
17
|
+
|
|
18
|
+
<tbody>
|
|
19
|
+
<% @invites.each do |invite| %>
|
|
20
|
+
<tr>
|
|
21
|
+
<td><%= link_to invite.email, invite %></td>
|
|
22
|
+
<td><%= user_link invite.inviting_user %></td>
|
|
23
|
+
<td><%= user_link invite.invited_user %></td>
|
|
24
|
+
<td><%= time_ago invite.created_at %></td>
|
|
25
|
+
<td><%= time_ago invite.accepted_at %></td>
|
|
26
|
+
<td><%= link_to 'Show', invite %></td>
|
|
27
|
+
<td><%= link_to 'Destroy', invite, method: :delete, data: { confirm: 'Are you sure?' } if user_can?(:delete_invite) %></td>
|
|
28
|
+
</tr>
|
|
29
|
+
<% end %>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
|
|
33
|
+
<br>
|
|
34
|
+
|
|
35
|
+
<%= link_to "Invited users", invites_path if user_can?(:list_invites) %>
|
|
36
|
+
|
|
37
|
+
<%= link_to "Invite new user", new_invite_path if user_can?(:create_invite) %>
|
|
38
|
+
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<% title ["Invite for #{@invite.email}"] %>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<strong>Email:</strong>
|
|
5
|
+
<%= @invite.email %>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p>
|
|
9
|
+
<strong>Invited by:</strong>
|
|
10
|
+
<%= user_link @invite.inviting_user %>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p>
|
|
14
|
+
<strong>Invited user:</strong>
|
|
15
|
+
<%= user_link @invite.invited_user %>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p>
|
|
19
|
+
<strong>Created at:</strong>
|
|
20
|
+
<%= time_ago @invite.created_at %>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p>
|
|
24
|
+
<strong>Accepted at:</strong>
|
|
25
|
+
<%= time_ago @invite.accepted_at %>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
<p>
|
|
29
|
+
<strong>Invite this user to sign up at:</strong>
|
|
30
|
+
<%= link_to main_app.login_url %>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<%= link_to 'Destroy', @invite, method: :delete, data: { confirm: 'Are you sure?' } if user_can?(:delete_invite) %>
|
|
34
|
+
<%= link_to 'Back', invites_path %>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<%= form_for(page) do |f| %>
|
|
2
|
+
<% if page.errors.any? %>
|
|
3
|
+
<div id="error_explanation">
|
|
4
|
+
<h2><%= pluralize(page.errors.count, "error") %> prohibited this page from being saved:</h2>
|
|
5
|
+
|
|
6
|
+
<ul>
|
|
7
|
+
<% page.errors.full_messages.each do |message| %>
|
|
8
|
+
<li><%= message %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<div class="field">
|
|
15
|
+
<%= f.label :title %>
|
|
16
|
+
<%= f.text_field :title %>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div class="field">
|
|
20
|
+
<%= f.label :content %>
|
|
21
|
+
<%= f.text_area :content %>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="actions">
|
|
25
|
+
<%= f.submit data: { disable_with: false } %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
28
|
+
|
|
29
|
+
<script type="text/javascript">
|
|
30
|
+
var select_image = {
|
|
31
|
+
name: "select-image",
|
|
32
|
+
action: function create_select_image_popup(editor) {
|
|
33
|
+
var refresh_links = function refresh_links() {
|
|
34
|
+
$(".insert-image li img").on('click', function(e) {
|
|
35
|
+
pos = simplemde.codemirror.getCursor();
|
|
36
|
+
simplemde.codemirror.setSelection(pos, pos);
|
|
37
|
+
var text = ".parent("li").attr("data-url") + ")";
|
|
38
|
+
simplemde.codemirror.replaceSelection(text);
|
|
39
|
+
modal.close();
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
var request_content = function request_content() {
|
|
44
|
+
$.ajax({
|
|
45
|
+
url: "<%= j image_dialog_uploaded_files_path %>",
|
|
46
|
+
success: function success(data, textStatus, jqXHR) {
|
|
47
|
+
modal.setContent(data);
|
|
48
|
+
refresh_links();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
var modal = new tingle.modal({
|
|
54
|
+
cssClass: ['insert-image'],
|
|
55
|
+
onOpen: function() {
|
|
56
|
+
request_content();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
modal.setContent("<span class=\"loading\">loading...</span>");
|
|
60
|
+
modal.open();
|
|
61
|
+
},
|
|
62
|
+
className: "fa fa-picture-o",
|
|
63
|
+
title: "Insert Image"
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
var select_file = {
|
|
67
|
+
name: "select-file",
|
|
68
|
+
action: function create_select_file_popup(editor) {
|
|
69
|
+
var refresh_links = function refresh_links() {
|
|
70
|
+
$(".insert-file li span").on('click', function(e) {
|
|
71
|
+
pos = simplemde.codemirror.getCursor();
|
|
72
|
+
simplemde.codemirror.setSelection(pos, pos);
|
|
73
|
+
var text = "[" + $(e.target).parent("li").attr("data-title") + "](" + $(e.target).parent("li").attr("data-url") + ")";
|
|
74
|
+
simplemde.codemirror.replaceSelection(text);
|
|
75
|
+
modal.close();
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
var request_content = function request_content() {
|
|
80
|
+
$.ajax({
|
|
81
|
+
url: "<%= j file_dialog_uploaded_files_path %>",
|
|
82
|
+
success: function success(data, textStatus, jqXHR) {
|
|
83
|
+
modal.setContent(data);
|
|
84
|
+
refresh_links();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
var modal = new tingle.modal({
|
|
90
|
+
cssClass: ['insert-file'],
|
|
91
|
+
onOpen: function() {
|
|
92
|
+
request_content();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
modal.setContent("<span class=\"loading\">loading...</span>");
|
|
96
|
+
modal.open();
|
|
97
|
+
},
|
|
98
|
+
className: "fa fa-file-o",
|
|
99
|
+
title: "Insert File"
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
var targetElement = document.getElementById("page_content");
|
|
103
|
+
|
|
104
|
+
var simplemde = new SimpleMDE({
|
|
105
|
+
element: targetElement,
|
|
106
|
+
toolbar: ["bold", "italic", "strikethrough", "heading", "|",
|
|
107
|
+
"code", "quote", "table", "horizontal-rule", "|",
|
|
108
|
+
"link", select_image, select_file, "unordered-list", "ordered-list", "|",
|
|
109
|
+
"preview", "side-by-side", "fullscreen"],
|
|
110
|
+
|
|
111
|
+
// a JS alert window appears asking for the link or image URL
|
|
112
|
+
promptURLs: true,
|
|
113
|
+
|
|
114
|
+
// force the textarea to stay up to date
|
|
115
|
+
forceSync: true,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
simplemde.originalContent = $(targetElement).val();
|
|
119
|
+
|
|
120
|
+
var thereAreUnsavedChanges = function() {
|
|
121
|
+
return !window.confirmedNavigatingAway && $(targetElement).val() != simplemde.originalContent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
$(window).bind("beforeunload", function(event) {
|
|
125
|
+
if (thereAreUnsavedChanges()) {
|
|
126
|
+
event.returnValue = "You have unsaved changes that may be lost.";
|
|
127
|
+
return event.returnValue;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
$("input[type=submit]").on("click", function() {
|
|
132
|
+
// if we're clicking Submit, we always want to navigate away
|
|
133
|
+
window.confirmedNavigatingAway = true;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Turbolinks 4 & 5
|
|
137
|
+
$(document).on("page:before-change turbolinks:before-visit", function() {
|
|
138
|
+
if (thereAreUnsavedChanges()) {
|
|
139
|
+
window.confirmedNavigatingAway = confirm("You have unsaved changes that may be lost.");
|
|
140
|
+
return window.confirmedNavigatingAway;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
</script>
|
|
144
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<% title [@page.title, "History"] %>
|
|
2
|
+
|
|
3
|
+
<h1>
|
|
4
|
+
History of
|
|
5
|
+
<%= link_to @page.title, wiki_path(@page) %>
|
|
6
|
+
<small><%= link_to ".json", page_history_path(@page, format: :json) %></small>
|
|
7
|
+
</h1>
|
|
8
|
+
|
|
9
|
+
<%= render "shared/histories", histories: @page.histories %>
|
|
10
|
+
|
|
11
|
+
<%= link_to 'Back', users_path %>
|