diff --git a/.gitignore b/.gitignore
index 131364d5b5b..4268486d7b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -109,3 +109,6 @@ bundler_stubs/*
vendor/bundle/*
*.db
+
+#ignore jetbrains ide file
+*.iml
diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6
index 71a8ca8fc12..067f6510814 100644
--- a/app/assets/javascripts/discourse/controllers/topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic.js.es6
@@ -687,6 +687,12 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
this.send('togglePinnedForUser');
},
+ print() {
+ if (this.siteSettings.max_prints_per_hour_per_user > 0) {
+ window.open(this.get('model.printUrl'), '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=315');
+ }
+ },
+
canMergeTopic: function() {
if (!this.get('model.details.can_move_posts')) return false;
return this.get('selectedPostsCount') > 0;
diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
index 5701e4b735e..49e543a52ee 100644
--- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
+++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
@@ -13,6 +13,8 @@ const bindings = {
'c': {handler: 'createTopic'},
'ctrl+f': {handler: 'showPageSearch', anonymous: true},
'command+f': {handler: 'showPageSearch', anonymous: true},
+ 'ctrl+p': {handler: 'printTopic', anonymous: true},
+ 'command+p': {handler: 'printTopic', anonymous: true},
'd': {postAction: 'deletePost'},
'e': {postAction: 'editPost'},
'end': {handler: 'goToLastPost', anonymous: true},
@@ -151,6 +153,15 @@ export default {
});
},
+ printTopic(event) {
+ Ember.run(() => {
+ if ($('.container.posts').length) {
+ event.preventDefault(); // We need to stop printing the current page in Firefox
+ this.container.lookup('controller:topic').print();
+ }
+ });
+ },
+
createTopic() {
this.container.lookup('controller:composer').open({action: Composer.CREATE_TOPIC, draftKey: Composer.CREATE_TOPIC});
},
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index f47342d7665..15b181fae88 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -134,6 +134,11 @@ const Topic = RestModel.extend({
return this.get('url') + (user ? '?u=' + user.get('username_lower') : '');
}.property('url'),
+ @computed('url')
+ printUrl(url) {
+ return url + '/print';
+ },
+
url: function() {
let slug = this.get('slug') || '';
if (slug.trim().length === 0) {
diff --git a/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs b/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs
index 4b1053397a2..3e6adc0fd25 100644
--- a/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs
+++ b/app/assets/javascripts/discourse/templates/modal/keyboard-shortcuts-help.hbs
@@ -56,6 +56,7 @@
{{{i18n 'keyboard_shortcuts_help.actions.mark_regular'}}}
{{{i18n 'keyboard_shortcuts_help.actions.mark_tracking'}}}
{{{i18n 'keyboard_shortcuts_help.actions.mark_watching'}}}
+ {{{i18n 'keyboard_shortcuts_help.actions.print'}}}
diff --git a/app/assets/stylesheets/common/components/keyboard_shortcuts.css.scss b/app/assets/stylesheets/common/components/keyboard_shortcuts.css.scss
index 098bfa420c5..04045f843f9 100644
--- a/app/assets/stylesheets/common/components/keyboard_shortcuts.css.scss
+++ b/app/assets/stylesheets/common/components/keyboard_shortcuts.css.scss
@@ -11,7 +11,7 @@
}
.keyboard-shortcuts-modal .modal-body {
- max-height: 520px;
+ max-height: 560px;
}
#keyboard-shortcuts-help {
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d9b6e5e6015..ec302c39666 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -53,7 +53,7 @@ class ApplicationController < ActionController::Base
end
def use_crawler_layout?
- @use_crawler_layout ||= (has_escaped_fragment? || CrawlerDetection.crawler?(request.user_agent))
+ @use_crawler_layout ||= (has_escaped_fragment? || CrawlerDetection.crawler?(request.user_agent) || params.key?("print"))
end
def add_readonly_header
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index d890410469a..1a15adc5b5d 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -3,6 +3,7 @@ require_dependency 'promotion'
require_dependency 'url_helper'
require_dependency 'topics_bulk_action'
require_dependency 'discourse_event'
+require_dependency 'rate_limiter'
class TopicsController < ApplicationController
before_filter :ensure_logged_in, only: [:timings,
@@ -58,6 +59,7 @@ class TopicsController < ApplicationController
username_filters = opts[:username_filters]
opts[:slow_platform] = true if slow_platform?
+ opts[:print] = true if params[:print].present?
opts[:username_filters] = username_filters.split(',') if username_filters.is_a?(String)
# Special case: a slug with a number in front should look by slug first before looking
@@ -67,6 +69,15 @@ class TopicsController < ApplicationController
return redirect_to_correct_topic(topic, opts[:post_number]) if topic && topic.visible
end
+ if opts[:print]
+ raise Discourse::InvalidAccess unless SiteSetting.max_prints_per_hour_per_user > 0
+ begin
+ RateLimiter.new(current_user, "print-topic-per-hour", SiteSetting.max_prints_per_hour_per_user, 1.hour).performed! unless @guardian.is_admin?
+ rescue RateLimiter::LimitExceeded
+ render_json_error(I18n.t("rate_limiter.slow_down"))
+ end
+ end
+
begin
@topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
rescue Discourse::NotFound
diff --git a/app/views/layouts/crawler.html.erb b/app/views/layouts/crawler.html.erb
index a2dfcf11a0b..0446c81f0bf 100644
--- a/app/views/layouts/crawler.html.erb
+++ b/app/views/layouts/crawler.html.erb
@@ -43,6 +43,11 @@
.topic-list > div {
margin-bottom: 15px;
}
+ body img.emoji {
+ width: 20px;
+ height: 20px;
+ vertical-align: middle;
+ }
@@ -71,4 +76,5 @@
<%= raw SiteCustomization.custom_body_tag(session[:preview_style]) %>
<%- end %>