Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI for list site settings #2207

Merged
merged 2 commits into from
Apr 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 82 additions & 0 deletions app/assets/javascripts/admin/components/list_setting_component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
Provide a nice GUI for a pipe-delimited list in the site settings.

@param settingValue is a reference to SiteSetting.value.

@class Discourse.ListSettingComponent
@extends Ember.Component
@namespace Discourse
@module Discourse
**/
Discourse.ListSettingComponent = Ember.Component.extend({
layoutName: 'components/list-setting',

init: function() {
this._super();
this.on("focusOut", this.uncacheValue);
this.set('children', []);
},

canAddNew: true,

readValues: function() {
return this.get('settingValue').split('|');
}.property('settingValue'),

/**
Transfer the debounced value into the settingValue parameter.

This will cause a redraw of the child textboxes.

@param newFocus {Number|undefined} Which list index to focus on next, or undefined to not refocus
**/
uncacheValue: function(newFocus) {
var oldValue = this.get('settingValue'),
newValue = this.get('settingValueCached'),
self = this;

if (newValue !== undefined && newValue !== oldValue) {
this.set('settingValue', newValue);
}

if (newFocus !== undefined && newFocus > 0) {
Em.run.schedule('afterRender', function() {
var children = self.get('children');
if (newFocus < children.length) {
$(children[newFocus].get('element')).focus();
} else if (newFocus === children.length) {
$(self.get('element')).children().children('.list-add-value').focus();
}
});
}
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does adding }.on("focusOut"), work here instead of having it in the init function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the focusOut event is on the item components. I'm testing an alternate method right now...


setItemValue: function(index, item) {
var values = this.get('readValues');
values[index] = item;

// Remove blank items
values = values.filter(function(s) { return s !== ''; });
this.setProperties({
settingValueCached: values.join('|'),
canAddNew: true
});
},

actions: {
addNewItem: function() {
var newValue = this.get('settingValue') + '|';
this.setProperties({
settingValue: newValue,
settingValueCached: newValue,
canAddNew: false
});

var self = this;
Em.run.schedule('afterRender', function() {
var children = self.get('children');
$(children[children.length - 1].get('element')).focus();
});
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
One item in a ListSetting.

@param parent is the ListSettingComponent.

@class Discourse.ListSettingItemComponent
@extends Ember.Component, Ember.TextSupport
@namespace Discourse
@module Discourse
**/
Discourse.ListSettingItemComponent = Ember.Component.extend(Ember.TextSupport, {
classNames: ['ember-text-field'],
tagName: "input",
attributeBindings: ['type', 'value', 'size', 'pattern'],

_initialize: function() {
// _parentView is the #each
// parent is the ListSettingComponent
this.setProperties({
value: this.get('_parentView.content'),
index: this.get('_parentView.contentIndex')
});
this.get('parent').get('children')[this.get('index')] = this;
}.on('init'),

markTab: function(e) {
var keyCode = e.keyCode || e.which;

if (keyCode === 9) {
this.set('nextIndex', this.get('index') + (e.shiftKey ? -1 : 1));
}
}.on('keyDown'),

reloadList: function() {
var nextIndex = this.get('nextIndex');
this.set('nextIndex', undefined); // one use only
this.get('parent').uncacheValue(nextIndex);
}.on('focusOut'),

_elementValueDidChange: function() {
this._super();
this.get('parent').setItemValue(this.get('index'), this.get('value'));
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class='setting-label'>
<h3>{{unbound setting}}</h3>
</div>
<div class="setting-value">
{{list-setting settingValue=value}}
<div class='desc'>{{unbound description}}</div>
</div>
{{#if dirty}}
<div class='setting-controls'>
<button class='btn ok no-text' {{action save this}}><i class='fa fa-check'></i></button>
<button class='btn cancel no-text' {{action cancel this}}><i class='fa fa-times'></i></button>
</div>
{{else}}
{{#if overridden}}
<button class='btn' href='#' {{action resetDefault this}}>{{i18n admin.site_settings.reset}}</button>
{{/if}}
{{/if}}
6 changes: 4 additions & 2 deletions app/assets/javascripts/admin/views/site_setting_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ Discourse.SiteSettingView = Discourse.View.extend(Discourse.ScrollTop, {
classNameBindings: [':row', ':setting', 'content.overridden'],

templateName: function() {

// If we're editing a boolean, return a different template
// If we're editing a boolean, show a checkbox
if (this.get('content.type') === 'bool') return 'admin/templates/site_settings/setting_bool';

// If we're editing an enum field, show a dropdown
if (this.get('content.type') === 'enum' ) return 'admin/templates/site_settings/setting_enum';

// If we're editing a list, show a list editor
if (this.get('content.type') === 'list' ) return 'admin/templates/site_settings/setting_list';

// Default to string editor
return 'admin/templates/site_settings/setting_string';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="ac-wrap clearfix input-setting-list">
{{#each readValues}}
{{list-setting-item parent=view action=update classNames="list-input-item"}}
{{/each}}
{{#if canAddNew}}
<button class="btn no-text list-add-value" {{action addNewItem}}><i class="fa fa-plus"></i></button>
{{/if}}
</div>
34 changes: 34 additions & 0 deletions app/assets/stylesheets/common/admin/admin_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,40 @@
@include medium-width { width: 314px; }
@include small-width { width: 284px; }
}
.input-setting-list {
width: 408px;
padding: 1px;
background-color: white;
border: 1px solid #e6e6e6;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(51, 51, 51, 0.3);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
transition: border linear 0.2s, box-shadow linear 0.2s;

.list-input-item {
width: 90px;
margin: 2px 1px;
background-color: white;
border: 1px solid #e6e6e6;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(51, 51, 51, 0.3);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
transition: border linear 0.2s, box-shadow linear 0.2s;

&:focus {
border-color: #00aaff;
outline: 0;
box-shadow: inset 0 1px 1px rgba(51, 51, 51, 0.3), 0 0 8px #00aaff;
}
}

.btn.list-add-value {
margin: 0px 3px;
padding: 4px 10px;
color: $link-color;
}
}


.desc {
padding-top: 3px;
Expand Down
4 changes: 2 additions & 2 deletions app/models/post.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ def whitelisted_spam_hosts

hosts = SiteSetting
.white_listed_spam_host_domains
.split(",")
.split('|')
.map{|h| h.strip}
.reject{|h| !h.include?(".")}
.reject{|h| !h.include?('.')}

hosts << GlobalSetting.hostname

Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.cs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ cs:
tos_url: "Pokud máte dokument 'Podmínky Používání' hostovaný samostatně, napište sem jeho plnou URL."
privacy_policy_url: "Pokud máte dokument 'Ochrana Soukromí' hostovaný samostatně, napište sem jeho plnou URL."
newuser_spam_host_threshold: "Kolikrát smí uživatel zaslat odkaz na stejný server v rámci příspěvků z nastavení 'newuser_spam_host_posts', než budou příspěvky považovány za spam."
white_listed_spam_host_domains: A comma delimited list of domains excluded from spam host testing, new users will be able to create an unrestricted count of posts with links to this domain
white_listed_spam_host_domains: A pipe-delimited list of domains excluded from spam host testing, new users will be able to create an unrestricted count of posts with links to this domain
staff_like_weight: "Extra hodnota pro 'líbí se' od uživatelů, kteří jsou součástí personálu webu."
reply_by_email_enabled: Jestli toto fórum umožňuje odpovědi emailem
reply_by_email_address: 'Šablona emailé adresy pro odpověď emailem, např. %{reply_key}@reply.myforum.com'
Expand Down
4 changes: 2 additions & 2 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ en:
max_image_height: "Maximum allowed height of images in a post"
category_featured_topics: "Number of topics displayed per category on the /categories page. After changing this value, it takes up to 15 minutes for the categories page to update."
add_rel_nofollow_to_user_content: "Add rel nofollow to all submitted user content, except for internal links (including parent domains) changing this requires you update all your baked markdown with: \"rake posts:rebake\""
exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"
exclude_rel_nofollow_domains: "A pipe-delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"

post_excerpt_maxlength: "Maximum length in chars of a post's excerpt"
post_onebox_maxlength: "Maximum length of a oneboxed Discourse post"
Expand Down Expand Up @@ -809,7 +809,7 @@ en:

newuser_spam_host_threshold: "How many times a new user can post a link to the same host within their `newuser_spam_host_posts` posts before being considered spam."

white_listed_spam_host_domains: "A comma delimited list of domains excluded from spam host testing, new users will be able to create an unrestricted count of posts with links to this domain"
white_listed_spam_host_domains: "A pipe-delimited list of domains excluded from spam host testing, new users will be able to create an unrestricted count of posts with links to this domain"
staff_like_weight: "Extra weighting factor given to likes when performed by staff."

reply_by_email_enabled: "Enable replying to topics via email"
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.id.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ id:
max_image_width: "Maximum allowed width of images in a post"
category_featured_topics: "Number of topics displayed per category in the /categories page"
add_rel_nofollow_to_user_content: "Add rel nofollow to all submitted user content, except for internal links (including parent domains) changing this requires you update all your baked markdown"
exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"
exclude_rel_nofollow_domains: "A pipe-delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"

post_excerpt_maxlength: "Maximum length in chars of a post's excerpt"
post_onebox_maxlength: "Maximum length of a oneboxed Discourse post"
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ ko:
max_image_height: "게시글에서 허용하는 이미지 최대 높이"
category_featured_topics: "Number of topics displayed per category in the /categories page"
add_rel_nofollow_to_user_content: "Add rel nofollow to all submitted user content, except for internal links (including parent domains) changing this requires you update all your baked markdown"
exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"
exclude_rel_nofollow_domains: "A pipe-delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"

post_excerpt_maxlength: "Maximum length in chars of a post's excerpt"
post_onebox_maxlength: "Maximum length of a oneboxed Discourse post"
Expand Down
21 changes: 17 additions & 4 deletions config/site_settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@ basic:
top_menu:
client: true
refresh: true
list: true
default: 'latest|new|unread|starred|top|categories'
post_menu:
client: true
list: true
default: 'like|edit|flag|delete|share|bookmark|reply'
share_links:
client: true
list: true
default: 'twitter|facebook|google+|email'
category_colors:
client: true
list: true
default: 'BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890'
enable_mobile_theme:
client: true
Expand Down Expand Up @@ -276,6 +280,7 @@ files:
client: true
default: '.jpg|.jpeg|.png|.gif'
refresh: true
list: true
crawl_images:
default:
test: false
Expand Down Expand Up @@ -340,17 +345,25 @@ security:

spam:
add_rel_nofollow_to_user_content: true
exclude_rel_nofollow_domains: ''
email_domains_blacklist: 'mailinator.com'
email_domains_whitelist: ''
exclude_rel_nofollow_domains:
default: ''
list: true
email_domains_blacklist:
default: 'mailinator.com'
list: true
email_domains_whitelist:
default: ''
list: true
flags_required_to_hide_post: 3
cooldown_minutes_after_hiding_posts: 10
num_flags_to_block_new_user: 3
num_users_to_block_new_user: 3
notify_mods_when_user_blocked: false
flag_sockpuppets: true
newuser_spam_host_threshold: 3
white_listed_spam_host_domains: ""
white_listed_spam_host_domains:
default: ''
list: true

rate_limits:
unique_posts_mins:
Expand Down
31 changes: 31 additions & 0 deletions db/migrate/20140407202158_site_setting_comma_to_pipe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class SiteSettingCommaToPipe < ActiveRecord::Migration
def up
execute <<SQL
UPDATE site_settings
SET value = replace(value, ',', '|')
WHERE name = 'white_listed_spam_host_domains'
;
SQL
execute <<SQL
UPDATE site_settings
SET value = replace(value, ',', '|')
WHERE name = 'exclude_rel_nofollow_domains'
;
SQL
end

def down
execute <<SQL
UPDATE site_settings
SET value = replace(value, '|', ',')
WHERE name = 'white_listed_spam_host_domains'
;
SQL
execute <<SQL
UPDATE site_settings
SET value = replace(value, '|', ',')
WHERE name = 'exclude_rel_nofollow_domains'
;
SQL
end
end
2 changes: 1 addition & 1 deletion lib/pretty_text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def self.add_rel_nofollow_to_user_content(html)
whitelist = []

domains = SiteSetting.exclude_rel_nofollow_domains
whitelist = domains.split(",") if domains.present?
whitelist = domains.split('|') if domains.present?

site_uri = nil
doc = Nokogiri::HTML.fragment(html)
Expand Down