mirror of
https://github.com/discourse/discourse.git
synced 2025-06-09 00:36:47 +08:00
Moved JSHint into Qunit suite. It's much harder to forget about now!
This commit is contained in:
63
.jshintrc
63
.jshintrc
@ -1,63 +0,0 @@
|
|||||||
{
|
|
||||||
"bitwise":true,
|
|
||||||
"newcap":true,
|
|
||||||
"eqeqeq":true,
|
|
||||||
"immed":false,
|
|
||||||
"nomen":false,
|
|
||||||
"onevar":false,
|
|
||||||
"plusplus":false,
|
|
||||||
"regexp":false,
|
|
||||||
"strict":false,
|
|
||||||
/*"undef":true,*/
|
|
||||||
"white":false,
|
|
||||||
"eqnull":false,
|
|
||||||
"debug":false,
|
|
||||||
"es5":false,
|
|
||||||
"evil":false,
|
|
||||||
"forin":false,
|
|
||||||
"laxbreak":false,
|
|
||||||
"sub":false,
|
|
||||||
"maxlen":200,
|
|
||||||
"indent":2,
|
|
||||||
"maxerr":50,
|
|
||||||
"passfail":false,
|
|
||||||
"predef":["Ember",
|
|
||||||
"jQuery",
|
|
||||||
"$",
|
|
||||||
"RSVP",
|
|
||||||
"Discourse",
|
|
||||||
"$LAB",
|
|
||||||
"Em",
|
|
||||||
"PreloadStore",
|
|
||||||
"Handlebars",
|
|
||||||
"I18n",
|
|
||||||
"bootbox",
|
|
||||||
"module",
|
|
||||||
"integration",
|
|
||||||
"test",
|
|
||||||
"ok",
|
|
||||||
"expect",
|
|
||||||
"equal",
|
|
||||||
"blank",
|
|
||||||
"present",
|
|
||||||
"visit",
|
|
||||||
"count",
|
|
||||||
"exists",
|
|
||||||
"asyncTest",
|
|
||||||
"find",
|
|
||||||
"resolvingPromise",
|
|
||||||
"sinon"],
|
|
||||||
"browser":true,
|
|
||||||
"rhino":false,
|
|
||||||
"devel":true,
|
|
||||||
"loopfunc":true,
|
|
||||||
"asi":true,
|
|
||||||
"boss":true,
|
|
||||||
"couch":true,
|
|
||||||
"curly":false,
|
|
||||||
"noarg":true,
|
|
||||||
"node":false,
|
|
||||||
"noempty":false,
|
|
||||||
"nonew":true,
|
|
||||||
"lastsemic":false
|
|
||||||
}
|
|
@ -9,6 +9,6 @@ before_script:
|
|||||||
- rake db:migrate
|
- rake db:migrate
|
||||||
- export RUBY_GC_MALLOC_LIMIT=50000000
|
- export RUBY_GC_MALLOC_LIMIT=50000000
|
||||||
bundler_args: --without development
|
bundler_args: --without development
|
||||||
script: 'rake jshint && rake spec && bundle exec rake qunit:test'
|
script: 'rake spec && bundle exec rake qunit:test'
|
||||||
services:
|
services:
|
||||||
- redis-server
|
- redis-server
|
||||||
|
2
Gemfile
2
Gemfile
@ -97,9 +97,7 @@ group :test do
|
|||||||
end
|
end
|
||||||
|
|
||||||
group :test, :development do
|
group :test, :development do
|
||||||
gem 'jshint_on_rails'
|
|
||||||
gem 'listen', require: false
|
gem 'listen', require: false
|
||||||
gem 'guard-jshint-on-rails', require: false
|
|
||||||
gem 'certified', require: false
|
gem 'certified', require: false
|
||||||
gem 'fabrication', require: false
|
gem 'fabrication', require: false
|
||||||
gem 'qunit-rails'
|
gem 'qunit-rails'
|
||||||
|
@ -199,9 +199,6 @@ GEM
|
|||||||
lumberjack (>= 1.0.2)
|
lumberjack (>= 1.0.2)
|
||||||
pry (>= 0.9.10)
|
pry (>= 0.9.10)
|
||||||
thor (>= 0.14.6)
|
thor (>= 0.14.6)
|
||||||
guard-jshint-on-rails (0.0.2)
|
|
||||||
guard (>= 1.0.0)
|
|
||||||
jshint_on_rails (>= 1.0.2)
|
|
||||||
guard-rspec (2.5.4)
|
guard-rspec (2.5.4)
|
||||||
guard (>= 1.1)
|
guard (>= 1.1)
|
||||||
rspec (~> 2.11)
|
rspec (~> 2.11)
|
||||||
@ -226,7 +223,6 @@ GEM
|
|||||||
image_sorcery (1.1.0)
|
image_sorcery (1.1.0)
|
||||||
in_threads (1.1.1)
|
in_threads (1.1.1)
|
||||||
journey (1.0.4)
|
journey (1.0.4)
|
||||||
jshint_on_rails (1.0.2)
|
|
||||||
json (1.7.7)
|
json (1.7.7)
|
||||||
jwt (0.1.8)
|
jwt (0.1.8)
|
||||||
multi_json (>= 1.5)
|
multi_json (>= 1.5)
|
||||||
@ -485,7 +481,6 @@ DEPENDENCIES
|
|||||||
fast_xs
|
fast_xs
|
||||||
fastimage
|
fastimage
|
||||||
fog
|
fog
|
||||||
guard-jshint-on-rails
|
|
||||||
guard-rspec
|
guard-rspec
|
||||||
guard-spork
|
guard-spork
|
||||||
handlebars-source (= 1.0.0.rc4)
|
handlebars-source (= 1.0.0.rc4)
|
||||||
@ -494,7 +489,6 @@ DEPENDENCIES
|
|||||||
hiredis
|
hiredis
|
||||||
image_optim
|
image_optim
|
||||||
image_sorcery
|
image_sorcery
|
||||||
jshint_on_rails
|
|
||||||
librarian (>= 0.0.25)
|
librarian (>= 0.0.25)
|
||||||
listen
|
listen
|
||||||
lru_redux
|
lru_redux
|
||||||
|
@ -3,14 +3,6 @@ require 'terminal-notifier-guard' if RUBY_PLATFORM.include?('darwin')
|
|||||||
phantom_path = File.expand_path('~/phantomjs/bin/phantomjs')
|
phantom_path = File.expand_path('~/phantomjs/bin/phantomjs')
|
||||||
phantom_path = nil unless File.exists?(phantom_path)
|
phantom_path = nil unless File.exists?(phantom_path)
|
||||||
|
|
||||||
# verify that we pass jshint
|
|
||||||
# see https://github.com/MrOrz/guard-jshint-on-rails
|
|
||||||
guard 'jshint-on-rails', config_path: 'config/jshint.yml' do
|
|
||||||
# watch for changes to application javascript files
|
|
||||||
watch(%r{^app/assets/javascripts/.*\.js$})
|
|
||||||
watch(%r{^spec/javascripts/.*\.js$})
|
|
||||||
end
|
|
||||||
|
|
||||||
unless ENV["USING_AUTOSPEC"]
|
unless ENV["USING_AUTOSPEC"]
|
||||||
|
|
||||||
puts "Sam strongly recommends you Run: `bundle exec rake autospec` in favor of guard for specs, set USING_AUTOSPEC in .rvmrc to disable from Guard"
|
puts "Sam strongly recommends you Run: `bundle exec rake autospec` in favor of guard for specs, set USING_AUTOSPEC in .rvmrc to disable from Guard"
|
||||||
|
@ -15,7 +15,7 @@ Discourse.AdminEmailPreviewDigestController = Discourse.ObjectController.extend(
|
|||||||
Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(function (email) {
|
Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(function (email) {
|
||||||
model.setProperties(email.getProperties('html_content', 'text_content'));
|
model.setProperties(email.getProperties('html_content', 'text_content'));
|
||||||
controller.set('loading', false);
|
controller.set('loading', false);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -94,7 +94,7 @@ Discourse.AdminUsersListController = Ember.ArrayController.extend(Discourse.Pres
|
|||||||
Discourse.AdminUser.findAll(this.get('query'), this.get('username')).then(function (result) {
|
Discourse.AdminUser.findAll(this.get('query'), this.get('username')).then(function (result) {
|
||||||
adminUsersListController.set('content', result);
|
adminUsersListController.set('content', result);
|
||||||
adminUsersListController.set('loading', false);
|
adminUsersListController.set('loading', false);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Discourse.FlaggedPost = Discourse.Post.extend({
|
|||||||
.map(function(v,k){
|
.map(function(v,k){
|
||||||
return Em.String.i18n("admin.flags.summary.action_type_" + k, {count: v.length});
|
return Em.String.i18n("admin.flags.summary.action_type_" + k, {count: v.length});
|
||||||
})
|
})
|
||||||
.join(",")
|
.join(",");
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
flaggers: function() {
|
flaggers: function() {
|
||||||
|
@ -20,7 +20,7 @@ Discourse.GithubCommit = Discourse.Model.extend({
|
|||||||
}.property("sha"),
|
}.property("sha"),
|
||||||
|
|
||||||
timeAgo: function() {
|
timeAgo: function() {
|
||||||
return moment(this.get('commit.committer.date')).relativeAge({format: 'medium', leaveAgo: true})
|
return moment(this.get('commit.committer.date')).relativeAge({format: 'medium', leaveAgo: true});
|
||||||
}.property("commit.committer.date")
|
}.property("commit.committer.date")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,12 +14,12 @@ Discourse.Group = Discourse.Model.extend({
|
|||||||
if(id && !this.get('loaded')) {
|
if(id && !this.get('loaded')) {
|
||||||
var group = this;
|
var group = this;
|
||||||
Discourse.ajax('/admin/groups/' + this.get('id') + '/users').then(function(payload){
|
Discourse.ajax('/admin/groups/' + this.get('id') + '/users').then(function(payload){
|
||||||
var users = Em.A()
|
var users = Em.A();
|
||||||
_.each(payload,function(user){
|
_.each(payload,function(user){
|
||||||
users.addObject(Discourse.User.create(user));
|
users.addObject(Discourse.User.create(user));
|
||||||
});
|
});
|
||||||
group.set('users', users)
|
group.set('users', users);
|
||||||
group.set('loaded', true)
|
group.set('loaded', true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -30,7 +30,7 @@ Discourse.Group = Discourse.Model.extend({
|
|||||||
if(users) {
|
if(users) {
|
||||||
usernames = _.map(users, function(user){
|
usernames = _.map(users, function(user){
|
||||||
return user.get('username');
|
return user.get('username');
|
||||||
}).join(',')
|
}).join(',');
|
||||||
}
|
}
|
||||||
return usernames;
|
return usernames;
|
||||||
}.property('users'),
|
}.property('users'),
|
||||||
|
@ -11,7 +11,7 @@ Discourse.AdminEmailIndexRoute = Discourse.Route.extend({
|
|||||||
setupController: function(controller) {
|
setupController: function(controller) {
|
||||||
Discourse.EmailSettings.find().then(function (model) {
|
Discourse.EmailSettings.find().then(function (model) {
|
||||||
controller.set('model', model);
|
controller.set('model', model);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
var oneWeekAgo = function() {
|
var oneWeekAgo = function() {
|
||||||
return moment().subtract('days',7).format('YYYY-MM-DD');
|
return moment().subtract('days',7).format('YYYY-MM-DD');
|
||||||
}
|
};
|
||||||
|
|
||||||
Discourse.AdminEmailPreviewDigestRoute = Discourse.Route.extend(Discourse.ModelReady, {
|
Discourse.AdminEmailPreviewDigestRoute = Discourse.Route.extend(Discourse.ModelReady, {
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ Discourse.AdminSiteContentEditRoute = Discourse.Route.extend({
|
|||||||
Discourse.SiteContent.find(Em.get(model, 'content_type')).then(function (sc) {
|
Discourse.SiteContent.find(Em.get(model, 'content_type')).then(function (sc) {
|
||||||
controller.set('content', sc);
|
controller.set('content', sc);
|
||||||
controller.set('loaded', true);
|
controller.set('loaded', true);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ Discourse = Ember.Application.createWithMixins({
|
|||||||
// Reloading will refresh unbound properties
|
// Reloading will refresh unbound properties
|
||||||
Discourse.KeyValueStore.abandonLocal();
|
Discourse.KeyValueStore.abandonLocal();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
authenticationComplete: function(options) {
|
authenticationComplete: function(options) {
|
||||||
@ -255,7 +255,7 @@ Discourse = Ember.Application.createWithMixins({
|
|||||||
if (fixture) {
|
if (fixture) {
|
||||||
return Ember.Deferred.promise(function(promise) {
|
return Ember.Deferred.promise(function(promise) {
|
||||||
promise.resolve(fixture);
|
promise.resolve(fixture);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ember.Deferred.promise(function (promise) {
|
return Ember.Deferred.promise(function (promise) {
|
||||||
@ -263,7 +263,7 @@ Discourse = Ember.Application.createWithMixins({
|
|||||||
args.success = function(xhr) {
|
args.success = function(xhr) {
|
||||||
Ember.run(promise, promise.resolve, xhr);
|
Ember.run(promise, promise.resolve, xhr);
|
||||||
if (oldSuccess) oldSuccess(xhr);
|
if (oldSuccess) oldSuccess(xhr);
|
||||||
}
|
};
|
||||||
|
|
||||||
var oldError = args.error;
|
var oldError = args.error;
|
||||||
args.error = function(xhr) {
|
args.error = function(xhr) {
|
||||||
@ -273,7 +273,7 @@ Discourse = Ember.Application.createWithMixins({
|
|||||||
|
|
||||||
promise.reject(xhr);
|
promise.reject(xhr);
|
||||||
if (oldError) oldError(xhr);
|
if (oldError) oldError(xhr);
|
||||||
}
|
};
|
||||||
|
|
||||||
// We default to JSON on GET. If we don't, sometimes if the server doesn't return the proper header
|
// We default to JSON on GET. If we don't, sometimes if the server doesn't return the proper header
|
||||||
// it will not be parsed as an object.
|
// it will not be parsed as an object.
|
||||||
@ -307,7 +307,7 @@ Discourse = Ember.Application.createWithMixins({
|
|||||||
bus.subscribe("/categories", function(data){
|
bus.subscribe("/categories", function(data){
|
||||||
var site = Discourse.Site.instance();
|
var site = Discourse.Site.instance();
|
||||||
_.each(data.categories,function(c){
|
_.each(data.categories,function(c){
|
||||||
site.updateCategory(c)
|
site.updateCategory(c);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ Discourse.BBCode = {
|
|||||||
extractQuotes: function(text) {
|
extractQuotes: function(text) {
|
||||||
var result = {text: "" + text, replacements: []};
|
var result = {text: "" + text, replacements: []};
|
||||||
|
|
||||||
var replacements = []
|
var replacements = [];
|
||||||
|
|
||||||
var matches;
|
var matches;
|
||||||
while (matches = Discourse.BBCode.QUOTE_REGEXP.exec(result.text)) {
|
while (matches = Discourse.BBCode.QUOTE_REGEXP.exec(result.text)) {
|
||||||
@ -178,7 +178,7 @@ Discourse.BBCode = {
|
|||||||
input = input.replace(r.key, val);
|
input = input.replace(r.key, val);
|
||||||
});
|
});
|
||||||
return input;
|
return input;
|
||||||
}
|
};
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
},
|
},
|
||||||
@ -192,21 +192,24 @@ Discourse.BBCode = {
|
|||||||
**/
|
**/
|
||||||
formatQuote: function(text, opts) {
|
formatQuote: function(text, opts) {
|
||||||
var args, matches, params, paramsSplit, paramsString, templateName, username;
|
var args, matches, params, paramsSplit, paramsString, templateName, username;
|
||||||
|
|
||||||
|
var splitter = function(p,i) {
|
||||||
|
if (i > 0) {
|
||||||
|
var assignment = p.split(':');
|
||||||
|
if (assignment[0] && assignment[1]) {
|
||||||
|
return params.push({
|
||||||
|
key: assignment[0],
|
||||||
|
value: assignment[1].trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
while (matches = this.QUOTE_REGEXP.exec(text)) {
|
while (matches = this.QUOTE_REGEXP.exec(text)) {
|
||||||
paramsString = matches[1].replace(/\"/g, '');
|
paramsString = matches[1].replace(/\"/g, '');
|
||||||
paramsSplit = paramsString.split(/\, */);
|
paramsSplit = paramsString.split(/\, */);
|
||||||
params = [];
|
params = [];
|
||||||
_.each(paramsSplit,function(p,i) {
|
_.each(paramsSplit, splitter);
|
||||||
if (i > 0) {
|
|
||||||
var assignment = p.split(':');
|
|
||||||
if (assignment[0] && assignment[1]) {
|
|
||||||
return params.push({
|
|
||||||
key: assignment[0],
|
|
||||||
value: assignment[1].trim()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
username = paramsSplit[0];
|
username = paramsSplit[0];
|
||||||
|
|
||||||
// remove leading <br>s
|
// remove leading <br>s
|
||||||
|
@ -59,12 +59,12 @@ Discourse.debouncePromise = function(func, wait) {
|
|||||||
timeout = Em.run.later(function () {
|
timeout = Em.run.later(function () {
|
||||||
timeout = null;
|
timeout = null;
|
||||||
func.apply(context, args).then(function (y) {
|
func.apply(context, args).then(function (y) {
|
||||||
promise.resolve(y)
|
promise.resolve(y);
|
||||||
});
|
});
|
||||||
}, wait);
|
}, wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint onecase:true */
|
||||||
|
|
||||||
Discourse.Formatter = (function(){
|
Discourse.Formatter = (function(){
|
||||||
|
|
||||||
var updateRelativeAge, autoUpdatingRelativeAge, relativeAge, relativeAgeTiny,
|
var updateRelativeAge, autoUpdatingRelativeAge, relativeAge, relativeAgeTiny,
|
||||||
@ -15,7 +17,7 @@ Discourse.Formatter = (function(){
|
|||||||
return str.replace(/\w\S*/g, function(txt){
|
return str.replace(/\w\S*/g, function(txt){
|
||||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
longDate = function(dt) {
|
longDate = function(dt) {
|
||||||
if (!dt) return;
|
if (!dt) return;
|
||||||
@ -105,7 +107,7 @@ Discourse.Formatter = (function(){
|
|||||||
|
|
||||||
var t = function(key, opts){
|
var t = function(key, opts){
|
||||||
return Ember.String.i18n("dates.medium" + (leaveAgo?"_with_ago":"") + "." + key, opts);
|
return Ember.String.i18n("dates.medium" + (leaveAgo?"_with_ago":"") + "." + key, opts);
|
||||||
}
|
};
|
||||||
|
|
||||||
switch(true){
|
switch(true){
|
||||||
case(distanceInMinutes >= 1 && distanceInMinutes <= 56):
|
case(distanceInMinutes >= 1 && distanceInMinutes <= 56):
|
||||||
|
@ -47,5 +47,5 @@ Discourse.KeyValueStore = {
|
|||||||
}
|
}
|
||||||
return localStorage[this.context + key];
|
return localStorage[this.context + key];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
@ -17,4 +17,4 @@ Discourse.Lightbox = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
@ -58,7 +58,7 @@ Discourse.Onebox = {
|
|||||||
var loadingFinished = function() {
|
var loadingFinished = function() {
|
||||||
$elem.removeClass('loading-onebox');
|
$elem.removeClass('loading-onebox');
|
||||||
$elem.data('onebox-loaded');
|
$elem.data('onebox-loaded');
|
||||||
}
|
};
|
||||||
|
|
||||||
var onebox = this;
|
var onebox = this;
|
||||||
promise.then(function(html) {
|
promise.then(function(html) {
|
||||||
|
@ -110,8 +110,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Discourse.Search = {
|
|||||||
if (!opts) opts = {};
|
if (!opts) opts = {};
|
||||||
|
|
||||||
// Only include the data we have
|
// Only include the data we have
|
||||||
var data = { term: term }
|
var data = { term: term };
|
||||||
if (opts.typeFilter) data.type_filter = opts.typeFilter;
|
if (opts.typeFilter) data.type_filter = opts.typeFilter;
|
||||||
|
|
||||||
if (opts.searchContext) {
|
if (opts.searchContext) {
|
||||||
@ -34,5 +34,5 @@ Discourse.Search = {
|
|||||||
return Discourse.ajax('/search', { data: data });
|
return Discourse.ajax('/search', { data: data });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ Discourse.EditCategoryController = Discourse.ObjectController.extend(Discourse.M
|
|||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
showCategoryTopic: function() {
|
showCategoryTopic: function() {
|
||||||
this.send('closeModal')
|
this.send('closeModal');
|
||||||
Discourse.URL.routeTo(this.get('topic_url'));
|
Discourse.URL.routeTo(this.get('topic_url'));
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -27,7 +27,7 @@ Discourse.FlagActionTypeController = Discourse.ObjectController.extend({
|
|||||||
showDescription: Em.computed.not('showMessageInput'),
|
showDescription: Em.computed.not('showMessageInput'),
|
||||||
|
|
||||||
customMessageLengthClasses: function() {
|
customMessageLengthClasses: function() {
|
||||||
return (this.get('message.length') < Discourse.SiteSettings.min_private_message_post_length) ? "too-short" : "ok"
|
return (this.get('message.length') < Discourse.SiteSettings.min_private_message_post_length) ? "too-short" : "ok";
|
||||||
}.property('message.length'),
|
}.property('message.length'),
|
||||||
|
|
||||||
customMessageLength: function() {
|
customMessageLength: function() {
|
||||||
|
@ -43,14 +43,14 @@ Discourse.FlagController = Discourse.ObjectController.extend(Discourse.ModalFunc
|
|||||||
}.property('selected.is_custom_flag'),
|
}.property('selected.is_custom_flag'),
|
||||||
|
|
||||||
takeAction: function() {
|
takeAction: function() {
|
||||||
this.createFlag({takeAction: true})
|
this.createFlag({takeAction: true});
|
||||||
this.set('hidden', true);
|
this.set('hidden', true);
|
||||||
},
|
},
|
||||||
|
|
||||||
createFlag: function(opts) {
|
createFlag: function(opts) {
|
||||||
var flagController = this;
|
var flagController = this;
|
||||||
var postAction = this.get('actionByName.' + this.get('selected.name_key'));
|
var postAction = this.get('actionByName.' + this.get('selected.name_key'));
|
||||||
var params = this.get('selected.is_custom_flag') ? {message: this.get('message')} : {}
|
var params = this.get('selected.is_custom_flag') ? {message: this.get('message')} : {};
|
||||||
|
|
||||||
if (opts) params = $.extend(params, opts);
|
if (opts) params = $.extend(params, opts);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ Discourse.LoginController = Discourse.Controller.extend(Discourse.ModalFunctiona
|
|||||||
// Failed to login
|
// Failed to login
|
||||||
loginController.flash(Em.String.i18n('login.error'), 'error');
|
loginController.flash(Em.String.i18n('login.error'), 'error');
|
||||||
loginController.set('loggingIn', false);
|
loginController.set('loggingIn', false);
|
||||||
})
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@ -153,7 +153,7 @@ Discourse.LoginController = Discourse.Controller.extend(Discourse.ModalFunctiona
|
|||||||
accountUsername: options.username,
|
accountUsername: options.username,
|
||||||
accountName: options.name,
|
accountName: options.name,
|
||||||
authOptions: Em.Object.create(options)
|
authOptions: Em.Object.create(options)
|
||||||
})
|
});
|
||||||
this.send('showCreateAccount');
|
this.send('showCreateAccount');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ Discourse.SearchController = Em.ArrayController.extend(Discourse.Presence, {
|
|||||||
var index = 0;
|
var index = 0;
|
||||||
results = _(['topic', 'category', 'user'])
|
results = _(['topic', 'category', 'user'])
|
||||||
.map(function(n){
|
.map(function(n){
|
||||||
return _(results).where({type: n}).first()
|
return _(results).where({type: n}).first();
|
||||||
})
|
})
|
||||||
.compact()
|
.compact()
|
||||||
.each(function(list){
|
.each(function(list){
|
||||||
|
@ -223,7 +223,7 @@ Handlebars.registerHelper('editDate', function(property, options) {
|
|||||||
**/
|
**/
|
||||||
Ember.Handlebars.registerHelper('percentile', function(property, options) {
|
Ember.Handlebars.registerHelper('percentile', function(property, options) {
|
||||||
var percentile = Ember.Handlebars.get(this, property, options);
|
var percentile = Ember.Handlebars.get(this, property, options);
|
||||||
return Math.round((1.0 - percentile) * 100)
|
return Math.round((1.0 - percentile) * 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,7 +236,7 @@ Ember.Handlebars.registerHelper('float', function(property, options) {
|
|||||||
var x = Ember.Handlebars.get(this, property, options);
|
var x = Ember.Handlebars.get(this, property, options);
|
||||||
if (!x) return "0";
|
if (!x) return "0";
|
||||||
if (Math.round(x) === x) return x;
|
if (Math.round(x) === x) return x;
|
||||||
return x.toFixed(3)
|
return x.toFixed(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,4 +66,4 @@ Discourse.ScrollingDOMMethods = {
|
|||||||
$(document).unbind('touchmove.discourse');
|
$(document).unbind('touchmove.discourse');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
@ -49,10 +49,10 @@ Discourse.CategoryList.reopenClass({
|
|||||||
var finder = null;
|
var finder = null;
|
||||||
if (filter === 'categories') {
|
if (filter === 'categories') {
|
||||||
finder = PreloadStore.getAndRemove("categories_list", function() {
|
finder = PreloadStore.getAndRemove("categories_list", function() {
|
||||||
return Discourse.ajax("/categories.json")
|
return Discourse.ajax("/categories.json");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
finder = Discourse.ajax("/" + filter + ".json")
|
finder = Discourse.ajax("/" + filter + ".json");
|
||||||
}
|
}
|
||||||
|
|
||||||
return finder.then(function(result) {
|
return finder.then(function(result) {
|
||||||
@ -63,7 +63,7 @@ Discourse.CategoryList.reopenClass({
|
|||||||
categories: route.categoriesFrom(result),
|
categories: route.categoriesFrom(result),
|
||||||
draft_key: result.category_list.draft_key,
|
draft_key: result.category_list.draft_key,
|
||||||
draft_sequence: result.category_list.draft_sequence
|
draft_sequence: result.category_list.draft_sequence
|
||||||
})
|
});
|
||||||
return categoryList;
|
return categoryList;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,4 @@ Discourse.PostActionType = Discourse.Model.extend({});
|
|||||||
|
|
||||||
Discourse.PostActionType.reopenClass({
|
Discourse.PostActionType.reopenClass({
|
||||||
MAX_MESSAGE_LENGTH: 500
|
MAX_MESSAGE_LENGTH: 500
|
||||||
})
|
});
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
// this allows you to track the selected item in an array, ghetto for now
|
// this allows you to track the selected item in an array, ghetto for now
|
||||||
Discourse.SelectableArray = Em.ArrayProxy.extend({
|
Discourse.SelectableArray = Em.ArrayProxy.extend({
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this.content = [];
|
this.content = [];
|
||||||
this._super();
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
selectIndex: function(index){
|
selectIndex: function(index){
|
||||||
this.select(this[index]);
|
this.select(this[index]);
|
||||||
},
|
},
|
||||||
|
|
||||||
select: function(selected){
|
select: function(selected){
|
||||||
_.each(this.content,function(item){
|
_.each(this.content,function(item){
|
||||||
if(item === selected){
|
if(item === selected){
|
||||||
Em.set(item, "active", true)
|
Em.set(item, "active", true);
|
||||||
} else {
|
} else {
|
||||||
if (item.get("active")) {
|
if (item.get("active")) {
|
||||||
Em.set(item, "active", false)
|
Em.set(item, "active", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.set("active", selected);
|
this.set("active", selected);
|
||||||
},
|
},
|
||||||
|
|
||||||
removeObject: function(object) {
|
removeObject: function(object) {
|
||||||
if(object === this.get("active")){
|
if(object === this.get("active")){
|
||||||
this.set("active", null);
|
this.set("active", null);
|
||||||
@ -27,4 +31,5 @@ Discourse.SelectableArray = Em.ArrayProxy.extend({
|
|||||||
|
|
||||||
this._super(object);
|
this._super(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,7 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
|
|
||||||
// The last post in the topic
|
// The last post in the topic
|
||||||
lastPost: function() {
|
lastPost: function() {
|
||||||
var posts = this.get('posts')
|
var posts = this.get('posts');
|
||||||
return posts[posts.length-1];
|
return posts[posts.length-1];
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
|
|
||||||
topic.set('allowed_users', Em.A(result.allowed_users));
|
topic.set('allowed_users', Em.A(result.allowed_users));
|
||||||
topic.set('loaded', true);
|
topic.set('loaded', true);
|
||||||
}
|
};
|
||||||
|
|
||||||
var errorLoadingTopic = function(result) {
|
var errorLoadingTopic = function(result) {
|
||||||
|
|
||||||
@ -295,22 +295,22 @@ Discourse.Topic = Discourse.Model.extend({
|
|||||||
|
|
||||||
// If the result was 404 the post is not found
|
// If the result was 404 the post is not found
|
||||||
if (result.status === 404) {
|
if (result.status === 404) {
|
||||||
topic.set('errorTitle', Em.String.i18n('topic.not_found.title'))
|
topic.set('errorTitle', Em.String.i18n('topic.not_found.title'));
|
||||||
topic.set('message', Em.String.i18n('topic.not_found.description'));
|
topic.set('message', Em.String.i18n('topic.not_found.description'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the result is 403 it means invalid access
|
// If the result is 403 it means invalid access
|
||||||
if (result.status === 403) {
|
if (result.status === 403) {
|
||||||
topic.set('errorTitle', Em.String.i18n('topic.invalid_access.title'))
|
topic.set('errorTitle', Em.String.i18n('topic.invalid_access.title'));
|
||||||
topic.set('message', Em.String.i18n('topic.invalid_access.description'));
|
topic.set('message', Em.String.i18n('topic.invalid_access.description'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise supply a generic error message
|
// Otherwise supply a generic error message
|
||||||
topic.set('errorTitle', Em.String.i18n('topic.server_error.title'))
|
topic.set('errorTitle', Em.String.i18n('topic.server_error.title'));
|
||||||
topic.set('message', Em.String.i18n('topic.server_error.description'));
|
topic.set('message', Em.String.i18n('topic.server_error.description'));
|
||||||
}
|
};
|
||||||
|
|
||||||
// Finally, call our find method
|
// Finally, call our find method
|
||||||
return Discourse.Topic.find(this.get('id'), {
|
return Discourse.Topic.find(this.get('id'), {
|
||||||
|
@ -148,7 +148,7 @@ Discourse.TopicList.reopenClass({
|
|||||||
var url = Discourse.getURL("/") + filter + ".json";
|
var url = Discourse.getURL("/") + filter + ".json";
|
||||||
if (excludeCategory) { url += "?exclude_category=" + excludeCategory; }
|
if (excludeCategory) { url += "?exclude_category=" + excludeCategory; }
|
||||||
return Discourse.ajax(url);
|
return Discourse.ajax(url);
|
||||||
}
|
};
|
||||||
|
|
||||||
return PreloadStore.getAndRemove("topic_list", finder).then(function(result) {
|
return PreloadStore.getAndRemove("topic_list", finder).then(function(result) {
|
||||||
var topicList = Discourse.TopicList.create({
|
var topicList = Discourse.TopicList.create({
|
||||||
|
@ -30,7 +30,7 @@ Discourse.Route.buildRoutes(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// the homepage is the first item of the 'top_menu' site setting
|
// the homepage is the first item of the 'top_menu' site setting
|
||||||
var settings = Discourse.SiteSettings || PreloadStore.get('siteSettings')
|
var settings = Discourse.SiteSettings || PreloadStore.get('siteSettings');
|
||||||
var homepage = settings.top_menu.split("|")[0].split(",")[0];
|
var homepage = settings.top_menu.split("|")[0].split(",")[0];
|
||||||
this.route(homepage, { path: '/' });
|
this.route(homepage, { path: '/' });
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@ var popstateReady = false;
|
|||||||
Ember.DiscourseLocation = Ember.Object.extend({
|
Ember.DiscourseLocation = Ember.Object.extend({
|
||||||
init: function() {
|
init: function() {
|
||||||
set(this, 'location', get(this, 'location') || window.location);
|
set(this, 'location', get(this, 'location') || window.location);
|
||||||
if ( $.inArray('state', $.event.props) < 0 )
|
if ( $.inArray('state', $.event.props) < 0 ) {
|
||||||
jQuery.event.props.push('state')
|
jQuery.event.props.push('state');
|
||||||
|
}
|
||||||
this.initState();
|
this.initState();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend({
|
|||||||
var uncategorized = Discourse.Category.uncategorizedInstance();
|
var uncategorized = Discourse.Category.uncategorizedInstance();
|
||||||
if (slug === uncategorized.get('slug')) return uncategorized;
|
if (slug === uncategorized.get('slug')) return uncategorized;
|
||||||
|
|
||||||
var category = categories.findProperty('slug', Em.get(params, 'slug'))
|
var category = categories.findProperty('slug', Em.get(params, 'slug'));
|
||||||
|
|
||||||
// In case the slug didn't work, try to find it by id instead.
|
// In case the slug didn't work, try to find it by id instead.
|
||||||
if (!category) {
|
if (!category) {
|
||||||
|
@ -34,7 +34,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
showPrivateInvite: function() {
|
showPrivateInvite: function() {
|
||||||
Discourse.Route.showModal(this, 'invitePrivate', this.modelFor('topic'))
|
Discourse.Route.showModal(this, 'invitePrivate', this.modelFor('topic'));
|
||||||
this.controllerFor('invitePrivate').setProperties({
|
this.controllerFor('invitePrivate').setProperties({
|
||||||
email: null,
|
email: null,
|
||||||
error: false,
|
error: false,
|
||||||
@ -46,7 +46,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||||||
showHistory: function(post) {
|
showHistory: function(post) {
|
||||||
Discourse.Route.showModal(this, 'history', post);
|
Discourse.Route.showModal(this, 'history', post);
|
||||||
this.controllerFor('history').refresh();
|
this.controllerFor('history').refresh();
|
||||||
this.controllerFor('modal').set('modalClass', 'history-modal')
|
this.controllerFor('modal').set('modalClass', 'history-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
mergeTopic: function() {
|
mergeTopic: function() {
|
||||||
|
@ -15,7 +15,7 @@ Discourse.AutoCloseFormView = Ember.View.extend({
|
|||||||
|
|
||||||
autoCloseChanged: function() {
|
autoCloseChanged: function() {
|
||||||
if( this.get('autoCloseDays') && this.get('autoCloseDays').length > 0 ) {
|
if( this.get('autoCloseDays') && this.get('autoCloseDays').length > 0 ) {
|
||||||
this.set('autoCloseDays', this.get('autoCloseDays').replace(/[^\d]/g, '') )
|
this.set('autoCloseDays', this.get('autoCloseDays').replace(/[^\d]/g, '') );
|
||||||
}
|
}
|
||||||
}.observes('autoCloseDays')
|
}.observes('autoCloseDays')
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ Discourse.ClearPinButton = Discourse.ButtonView.extend({
|
|||||||
// Hide the button if it becomes unpinned
|
// Hide the button if it becomes unpinned
|
||||||
unpinned: function() {
|
unpinned: function() {
|
||||||
// When not logged in don't show the button
|
// When not logged in don't show the button
|
||||||
if (!Discourse.User.current()) return 'hidden'
|
if (!Discourse.User.current()) return 'hidden';
|
||||||
return this.get('controller.pinned') ? null : 'hidden';
|
return this.get('controller.pinned') ? null : 'hidden';
|
||||||
}.property('controller.pinned'),
|
}.property('controller.pinned'),
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ Discourse.HeaderView = Discourse.View.extend({
|
|||||||
if(logo && logo.length > 1) {
|
if(logo && logo.length > 1) {
|
||||||
result += "<img class='logo-big' src=\"" + logo + "\" alt=\"" + Discourse.SiteSettings.title + "\" id='site-logo'>";
|
result += "<img class='logo-big' src=\"" + logo + "\" alt=\"" + Discourse.SiteSettings.title + "\" id='site-logo'>";
|
||||||
} else {
|
} else {
|
||||||
result += "<h2 class='text-logo' id='site-text-logo'>" + Discourse.SiteSettings.title + "</h2>"
|
result += "<h2 class='text-logo' id='site-text-logo'>" + Discourse.SiteSettings.title + "</h2>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += "</a></div>";
|
result += "</a></div>";
|
||||||
|
@ -66,7 +66,7 @@ Discourse.ListTopicsView = Discourse.View.extend(Discourse.Scrolling, {
|
|||||||
if (!hasMoreResults) {
|
if (!hasMoreResults) {
|
||||||
listTopicsView.get('eyeline').flushRest();
|
listTopicsView.get('eyeline').flushRest();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Remember where we were scrolled to
|
// Remember where we were scrolled to
|
||||||
|
@ -31,7 +31,7 @@ Discourse.PopupInputTipView = Discourse.View.extend({
|
|||||||
|
|
||||||
bounce: function() {
|
bounce: function() {
|
||||||
if( this.get('shownAt') ) {
|
if( this.get('shownAt') ) {
|
||||||
var $elem = this.$()
|
var $elem = this.$();
|
||||||
if( !this.animateAttribute ) {
|
if( !this.animateAttribute ) {
|
||||||
this.animateAttribute = $elem.css('left') === 'auto' ? 'right' : 'left';
|
this.animateAttribute = $elem.css('left') === 'auto' ? 'right' : 'left';
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ Discourse.TopicClosingView = Discourse.View.extend({
|
|||||||
|
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function() {
|
||||||
if( this.delayedRerender ) {
|
if( this.delayedRerender ) {
|
||||||
Em.run.cancel(this.delayedRerender)
|
Em.run.cancel(this.delayedRerender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,7 @@ Discourse.TopicSummaryView = Discourse.ContainerView.extend({
|
|||||||
templateName: 'topic_summary/info',
|
templateName: 'topic_summary/info',
|
||||||
topic: this.get('topic'),
|
topic: this.get('topic'),
|
||||||
summaryView: this
|
summaryView: this
|
||||||
})
|
});
|
||||||
|
|
||||||
this.trigger('appendSummaryInformation', this);
|
this.trigger('appendSummaryInformation', this);
|
||||||
},
|
},
|
||||||
|
@ -106,7 +106,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
|||||||
this.resetExamineDockCache();
|
this.resetExamineDockCache();
|
||||||
|
|
||||||
// this happens after route exit, stuff could have trickled in
|
// this happens after route exit, stuff could have trickled in
|
||||||
this.set('controller.controllers.header.showExtraInfo', false)
|
this.set('controller.controllers.header.showExtraInfo', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement: function(e) {
|
didInsertElement: function(e) {
|
||||||
|
@ -28,4 +28,4 @@ Discourse.View.reopenClass({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
||||||
|
@ -20,7 +20,7 @@ class DiscourseIIFE < Sprockets::Processor
|
|||||||
return data if path =~ /\.shbrs/
|
return data if path =~ /\.shbrs/
|
||||||
return data if path =~ /\.hbrs/
|
return data if path =~ /\.hbrs/
|
||||||
|
|
||||||
"(function () {\n\nvar $ = window.jQuery;\n\n#{data}\n\n})(this);"
|
"(function () {\n\nvar $ = window.jQuery;\n// IIFE Wrapped Content Begins:\n\n#{data}\n\n// IIFE Wrapped Content Ends\n\n })(this);"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -1,10 +1,10 @@
|
|||||||
/*global md5:true */
|
/*global md5:true */
|
||||||
|
|
||||||
module("Discourse.BBCode");
|
module("Discourse.BBCode");
|
||||||
|
|
||||||
var format = function(input, expected, text) {
|
var format = function(input, expected, text) {
|
||||||
|
// testing 1 2 3
|
||||||
equal(Discourse.BBCode.format(input, {lookupAvatar: false}), expected, text);
|
equal(Discourse.BBCode.format(input, {lookupAvatar: false}), expected, text);
|
||||||
}
|
};
|
||||||
|
|
||||||
test('basic bbcode', function() {
|
test('basic bbcode', function() {
|
||||||
format("[b]strong[/b]", "<span class='bbcode-b'>strong</span>", "bolds text");
|
format("[b]strong[/b]", "<span class='bbcode-b'>strong</span>", "bolds text");
|
||||||
@ -50,7 +50,7 @@ test("quotes", function() {
|
|||||||
|
|
||||||
var formatQuote = function(val, expected, text) {
|
var formatQuote = function(val, expected, text) {
|
||||||
equal(Discourse.BBCode.buildQuoteBBCode(post, val), expected, text);
|
equal(Discourse.BBCode.buildQuoteBBCode(post, val), expected, text);
|
||||||
}
|
};
|
||||||
|
|
||||||
formatQuote(undefined, "", "empty string for undefined content");
|
formatQuote(undefined, "", "empty string for undefined content");
|
||||||
formatQuote(null, "", "empty string for null content");
|
formatQuote(null, "", "empty string for null content");
|
||||||
|
@ -37,9 +37,10 @@ module("Discourse.ClickTrack", {
|
|||||||
|
|
||||||
var track = Discourse.ClickTrack.trackClick;
|
var track = Discourse.ClickTrack.trackClick;
|
||||||
|
|
||||||
|
// test
|
||||||
var generateClickEventOn = function(selector) {
|
var generateClickEventOn = function(selector) {
|
||||||
return $.Event("click", { currentTarget: $(selector)[0] });
|
return $.Event("click", { currentTarget: $(selector)[0] });
|
||||||
}
|
};
|
||||||
|
|
||||||
test("does not track clicks on lightboxes", function() {
|
test("does not track clicks on lightboxes", function() {
|
||||||
var clickEvent = generateClickEventOn('.lightbox');
|
var clickEvent = generateClickEventOn('.lightbox');
|
||||||
@ -57,11 +58,11 @@ test("it calls preventDefault when clicking on an a", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("does not track clicks on back buttons", function() {
|
test("does not track clicks on back buttons", function() {
|
||||||
ok(track(generateClickEventOn('.back')))
|
ok(track(generateClickEventOn('.back')));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("does not track clicks on quote buttons", function() {
|
test("does not track clicks on quote buttons", function() {
|
||||||
ok(track(generateClickEventOn('.quote-other-topic')))
|
ok(track(generateClickEventOn('.quote-other-topic')));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("removes the href and put it as a data attribute", function() {
|
test("removes the href and put it as a data attribute", function() {
|
||||||
@ -99,7 +100,7 @@ test("updates badge counts correctly", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var trackRightClick = function() {
|
var trackRightClick = function() {
|
||||||
var clickEvent = generateClickEventOn('a')
|
var clickEvent = generateClickEventOn('a');
|
||||||
clickEvent.which = 3;
|
clickEvent.which = 3;
|
||||||
return track(clickEvent);
|
return track(clickEvent);
|
||||||
};
|
};
|
||||||
|
@ -27,15 +27,15 @@ test("formating medium length dates", function() {
|
|||||||
format = "medium";
|
format = "medium";
|
||||||
var strip = function(html){
|
var strip = function(html){
|
||||||
return $(html).text();
|
return $(html).text();
|
||||||
}
|
};
|
||||||
|
|
||||||
var shortDate = function(days){
|
var shortDate = function(days){
|
||||||
return moment().subtract('days', days).format('D MMM');
|
return moment().subtract('days', days).format('D MMM');
|
||||||
}
|
};
|
||||||
|
|
||||||
var shortDateYear = function(days){
|
var shortDateYear = function(days){
|
||||||
return moment().subtract('days', days).format('D MMM, YYYY');
|
return moment().subtract('days', days).format('D MMM, YYYY');
|
||||||
}
|
};
|
||||||
|
|
||||||
leaveAgo = true;
|
leaveAgo = true;
|
||||||
equal(strip(formatMins(1.4)), "1 min ago");
|
equal(strip(formatMins(1.4)), "1 min ago");
|
||||||
|
@ -12,11 +12,10 @@ var cooked = function(input, expected, text) {
|
|||||||
|
|
||||||
var cookedOptions = function(input, opts, expected, text) {
|
var cookedOptions = function(input, opts, expected, text) {
|
||||||
equal(Discourse.Markdown.cook(input, opts), expected, text);
|
equal(Discourse.Markdown.cook(input, opts), expected, text);
|
||||||
}
|
};
|
||||||
|
|
||||||
test("basic cooking", function() {
|
test("basic cooking", function() {
|
||||||
cooked("hello", "<p>hello</p>", "surrounds text with paragraphs");
|
cooked("hello", "<p>hello</p>", "surrounds text with paragraphs");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Line Breaks", function() {
|
test("Line Breaks", function() {
|
||||||
@ -29,10 +28,10 @@ test("Line Breaks", function() {
|
|||||||
cookedOptions(input,
|
cookedOptions(input,
|
||||||
{traditional_markdown_linebreaks: true},
|
{traditional_markdown_linebreaks: true},
|
||||||
traditionalOutput,
|
traditionalOutput,
|
||||||
"It supports traditional markdown via an option")
|
"It supports traditional markdown via an option");
|
||||||
|
|
||||||
Discourse.SiteSettings.traditional_markdown_linebreaks = true;
|
Discourse.SiteSettings.traditional_markdown_linebreaks = true;
|
||||||
cooked(input, traditionalOutput, "It supports traditional markdown via a Site Setting")
|
cooked(input, traditionalOutput, "It supports traditional markdown via a Site Setting");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
182
test/javascripts/jshint_all.js.erb
Normal file
182
test/javascripts/jshint_all.js.erb
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
module("JSHint");
|
||||||
|
|
||||||
|
var qHint = function(name, sourceFile, options, globals) {
|
||||||
|
if (sourceFile === undefined || typeof(sourceFile) == "object") {
|
||||||
|
// jsHintTest('file.js', [options])
|
||||||
|
globals = options;
|
||||||
|
options = sourceFile;
|
||||||
|
sourceFile = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asyncTest(name, function() {
|
||||||
|
qHint.sendRequest(sourceFile, function(req) {
|
||||||
|
start();
|
||||||
|
|
||||||
|
if (req.status == 200) {
|
||||||
|
|
||||||
|
var text = req.responseText;
|
||||||
|
|
||||||
|
// Remove our generate IIFEs so we get the same line numbers as original
|
||||||
|
// files
|
||||||
|
text = text.replace(/^[^]*\/\/ IIFE Wrapped Content Begins:\n\n/m, "");
|
||||||
|
text = text.replace(/\n\n\/\/ IIFE Wrapped Content Ends[^]*$/m, "");
|
||||||
|
qHint.validateFile(text, options, globals);
|
||||||
|
} else {
|
||||||
|
ok(false, "HTTP error " + req.status +
|
||||||
|
" while fetching " + sourceFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
qHint.validateFile = function (source, options, globals) {
|
||||||
|
var i, len, err;
|
||||||
|
|
||||||
|
if (JSHINT(source, options, globals)) {
|
||||||
|
ok(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, len = JSHINT.errors.length; i < len; i++) {
|
||||||
|
err = JSHINT.errors[i];
|
||||||
|
if (!err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(false, err.reason +
|
||||||
|
" on line " + err.line +
|
||||||
|
", character " + err.character);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var XMLHttpFactories = [
|
||||||
|
function () { return new XMLHttpRequest(); },
|
||||||
|
function () { return new ActiveXObject("Msxml2.XMLHTTP"); },
|
||||||
|
function () { return new ActiveXObject("Msxml3.XMLHTTP"); },
|
||||||
|
function () { return new ActiveXObject("Microsoft.XMLHTTP"); }
|
||||||
|
];
|
||||||
|
|
||||||
|
function createXMLHTTPObject() {
|
||||||
|
for (var i = 0; i < XMLHttpFactories.length; i++) {
|
||||||
|
try {
|
||||||
|
return XMLHttpFactories[i]();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modified version of XHR script by PPK
|
||||||
|
// http://www.quirksmode.org/js/xmlhttp.html
|
||||||
|
// attached to qHint to allow substitution / mocking
|
||||||
|
qHint.sendRequest = function (url, callback) {
|
||||||
|
var req = createXMLHTTPObject();
|
||||||
|
if (!req) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var method = "GET";
|
||||||
|
req.open(method,url + "?" + (new Date().getTime()),true);
|
||||||
|
req.onreadystatechange = function () {
|
||||||
|
if (req.readyState != 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(req);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
req.send();
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsHintOpts = {
|
||||||
|
"predef":["Ember",
|
||||||
|
"jQuery",
|
||||||
|
"$",
|
||||||
|
"RSVP",
|
||||||
|
"Discourse",
|
||||||
|
"$LAB",
|
||||||
|
"Em",
|
||||||
|
"PreloadStore",
|
||||||
|
"Handlebars",
|
||||||
|
"I18n",
|
||||||
|
"bootbox",
|
||||||
|
"module",
|
||||||
|
"integration",
|
||||||
|
"test",
|
||||||
|
"ok",
|
||||||
|
"expect",
|
||||||
|
"equal",
|
||||||
|
"blank",
|
||||||
|
"present",
|
||||||
|
"visit",
|
||||||
|
"count",
|
||||||
|
"exists",
|
||||||
|
"asyncTest",
|
||||||
|
"find",
|
||||||
|
"resolvingPromise",
|
||||||
|
"sinon",
|
||||||
|
"moment",
|
||||||
|
"start",
|
||||||
|
"_",
|
||||||
|
"console",
|
||||||
|
"alert"],
|
||||||
|
"node" : false,
|
||||||
|
"browser" : true,
|
||||||
|
"boss" : true,
|
||||||
|
"curly": false,
|
||||||
|
"debug": false,
|
||||||
|
"devel": false,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"evil": true,
|
||||||
|
"forin": false,
|
||||||
|
"immed": false,
|
||||||
|
"laxbreak": false,
|
||||||
|
"newcap": true,
|
||||||
|
"noarg": true,
|
||||||
|
"noempty": false,
|
||||||
|
"nonew": false,
|
||||||
|
"nomen": false,
|
||||||
|
"onevar": false,
|
||||||
|
"plusplus": false,
|
||||||
|
"regexp": false,
|
||||||
|
"undef": true,
|
||||||
|
"sub": true,
|
||||||
|
"strict": false,
|
||||||
|
"white": false,
|
||||||
|
"eqnull": true,
|
||||||
|
"lastsemic": true
|
||||||
|
};
|
||||||
|
|
||||||
|
<%
|
||||||
|
def jshint(dir, remove, to_ignore)
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
Dir.glob(dir).each do |f|
|
||||||
|
filename = f.sub("#{Rails.root}#{remove}", "")
|
||||||
|
|
||||||
|
ok = true
|
||||||
|
to_ignore.each do |ig|
|
||||||
|
ok = false if (filename =~ ig)
|
||||||
|
end
|
||||||
|
|
||||||
|
result << "qHint('#{filename}', '/assets/#{filename}', jsHintOpts);\n" if ok
|
||||||
|
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%= jshint("#{Rails.root}/test/**/*.js",
|
||||||
|
"/test/javascripts/",
|
||||||
|
[/helpers\//]) %>
|
||||||
|
|
||||||
|
<%= jshint("#{Rails.root}/app/assets/javascripts/**/*.js",
|
||||||
|
"/app/assets/javascripts/",
|
||||||
|
[/external\//,
|
||||||
|
/external_development\//,
|
||||||
|
/external_production\//,
|
||||||
|
/defer\//,
|
||||||
|
/locales\//]) %>
|
@ -4,7 +4,7 @@ test('slugFor', function(){
|
|||||||
|
|
||||||
var slugFor = function(args, val, text) {
|
var slugFor = function(args, val, text) {
|
||||||
equal(Discourse.Category.slugFor(args), val, text);
|
equal(Discourse.Category.slugFor(args), val, text);
|
||||||
}
|
};
|
||||||
|
|
||||||
slugFor({slug: 'hello'}, "hello", "It calculates the proper slug for hello");
|
slugFor({slug: 'hello'}, "hello", "It calculates the proper slug for hello");
|
||||||
slugFor({id: 123, slug: ''}, "123-category", "It returns id-category for empty strings");
|
slugFor({id: 123, slug: ''}, "123-category", "It returns id-category for empty strings");
|
||||||
|
@ -21,7 +21,7 @@ test('missingReplyCharacters', function() {
|
|||||||
var missingReplyCharacters = function(val, isPM, expected, message) {
|
var missingReplyCharacters = function(val, isPM, expected, message) {
|
||||||
var composer = Discourse.Composer.create({ reply: val, creatingPrivateMessage: isPM });
|
var composer = Discourse.Composer.create({ reply: val, creatingPrivateMessage: isPM });
|
||||||
equal(composer.get('missingReplyCharacters'), expected, message);
|
equal(composer.get('missingReplyCharacters'), expected, message);
|
||||||
}
|
};
|
||||||
|
|
||||||
missingReplyCharacters('hi', false, Discourse.SiteSettings.min_post_length - 2, 'too short public post');
|
missingReplyCharacters('hi', false, Discourse.SiteSettings.min_post_length - 2, 'too short public post');
|
||||||
missingReplyCharacters('hi', true, Discourse.SiteSettings.min_private_message_post_length - 2, 'too short private message');
|
missingReplyCharacters('hi', true, Discourse.SiteSettings.min_private_message_post_length - 2, 'too short private message');
|
||||||
@ -31,7 +31,7 @@ test('missingTitleCharacters', function() {
|
|||||||
var missingTitleCharacters = function(val, isPM, expected, message) {
|
var missingTitleCharacters = function(val, isPM, expected, message) {
|
||||||
var composer = Discourse.Composer.create({ title: val, creatingPrivateMessage: isPM });
|
var composer = Discourse.Composer.create({ title: val, creatingPrivateMessage: isPM });
|
||||||
equal(composer.get('missingTitleCharacters'), expected, message);
|
equal(composer.get('missingTitleCharacters'), expected, message);
|
||||||
}
|
};
|
||||||
|
|
||||||
missingTitleCharacters('hi', false, Discourse.SiteSettings.min_topic_title_length - 2, 'too short post title');
|
missingTitleCharacters('hi', false, Discourse.SiteSettings.min_topic_title_length - 2, 'too short post title');
|
||||||
missingTitleCharacters('z', true, Discourse.SiteSettings.min_private_message_title_length - 1, 'too short pm title');
|
missingTitleCharacters('z', true, Discourse.SiteSettings.min_private_message_title_length - 1, 'too short pm title');
|
||||||
|
@ -32,8 +32,9 @@
|
|||||||
//= require_tree ../../app/assets/javascripts/defer
|
//= require_tree ../../app/assets/javascripts/defer
|
||||||
|
|
||||||
|
|
||||||
//= require sinon-1.7.1.js
|
//= require sinon-1.7.1
|
||||||
//= require sinon-qunit-1.0.0.js
|
//= require sinon-qunit-1.0.0
|
||||||
|
//= require jshint
|
||||||
|
|
||||||
//= require helpers/qunit_helpers
|
//= require helpers/qunit_helpers
|
||||||
//= require helpers/assertions
|
//= require helpers/assertions
|
||||||
@ -41,6 +42,7 @@
|
|||||||
//= require_tree ./fixtures
|
//= require_tree ./fixtures
|
||||||
//= require_tree .
|
//= require_tree .
|
||||||
//= require_self
|
//= require_self
|
||||||
|
//= require jshint_all
|
||||||
|
|
||||||
// sinon settings
|
// sinon settings
|
||||||
sinon.config = {
|
sinon.config = {
|
||||||
|
4023
vendor/assets/javascripts/jshint.js
vendored
Normal file
4023
vendor/assets/javascripts/jshint.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user