Merge branch 'master' into vagrant-chef

This commit is contained in:
Elliot Murphy 2013-02-07 13:58:28 -05:00
commit 9e198c3ac5
235 changed files with 3209 additions and 1173 deletions

View File

@ -2,7 +2,7 @@
## Before You Start ## Before You Start
Anyone wishing to contribute to the **[Discourse/Discourse](https://github.com/discourse/discourse)** project **MUST read & sign the [Electronic Discourse Forums Contribution License Agreement](https://docs.google.com/a/discourse.org/spreadsheet/viewform?formkey=dGUwejFfbDhDYXR4bVFMRG1TUENqLWc6MQ)**. The Discourse team is legally prevented from accepting any pull requests from users who have not signed the CLA first. Anyone wishing to contribute to the **[Discourse/Discourse](https://github.com/discourse/discourse)** project **MUST read & sign the [Electronic Discourse Forums Contribution License Agreement](http://www.discourse.org/cla)**. The Discourse team is legally prevented from accepting any pull requests from users who have not signed the CLA first.
## Reporting Bugs ## Reporting Bugs
@ -20,7 +20,7 @@ Anyone wishing to contribute to the **[Discourse/Discourse](https://github.com/d
## Requesting New Features ## Requesting New Features
1. Do not submit a feature request on GitHub; all feature requests on GitHub will be closed. Instead, visit the Discourse development forums, and search for the "Feature Request" category, which will filter a list of outstanding requests. Review this list for similar feature requests. It's possible somebody has already asked for this feature or provided a pull request that we're still discussing. 1. Do not submit a feature request on GitHub; all feature requests on GitHub will be closed. Instead, visit the **[Discourse development forums](http://meta.discourse.org/category/feature)**, and search for the "Feature" category, which will filter a list of outstanding requests. Review this list for similar feature requests. It's possible somebody has already asked for this feature or provided a pull request that we're still discussing.
2. Provide a clear and detailed explanation of the feature you want and why it's important to add. The feature must apply to a wide array of users of Discourse; for smaller, more targeted "one-off" features, you might consider writing a plugin for Discourse. You may also want to provide us with some advance documentation on the feature, which will help the community to better understand where it will fit. 2. Provide a clear and detailed explanation of the feature you want and why it's important to add. The feature must apply to a wide array of users of Discourse; for smaller, more targeted "one-off" features, you might consider writing a plugin for Discourse. You may also want to provide us with some advance documentation on the feature, which will help the community to better understand where it will fit.

View File

@ -1,5 +1,6 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'slim' # required for sidekiq-web
gem 'redis' gem 'redis'
gem 'redis-rails' gem 'redis-rails'
gem 'hiredis' gem 'hiredis'

View File

@ -344,7 +344,6 @@ GEM
temple (0.4.1) temple (0.4.1)
terminal-notifier-guard (1.5.3) terminal-notifier-guard (1.5.3)
terminal-table (1.4.5) terminal-table (1.4.5)
test-unit (2.5.4)
therubyracer (0.11.3) therubyracer (0.11.3)
libv8 (~> 3.11.8.12) libv8 (~> 3.11.8.12)
ref ref
@ -391,7 +390,6 @@ DEPENDENCIES
guard-jasmine guard-jasmine
guard-rspec guard-rspec
guard-spork guard-spork
haml
has_ip_address has_ip_address
hiredis hiredis
hpricot hpricot
@ -432,9 +430,8 @@ DEPENDENCIES
simple_handlebars_rails! simple_handlebars_rails!
simplecov simplecov
sinatra sinatra
slim (<= 1.3.0) slim
terminal-notifier-guard terminal-notifier-guard
test-unit
therubyracer therubyracer
thin thin
turbo-sprockets-rails3 turbo-sprockets-rails3

View File

@ -6,7 +6,7 @@ window.Discourse.AdminEmailLogsController = Ember.ArrayController.extend Discour
sendTestEmail: -> sendTestEmail: ->
@set('sentTestEmail', false) @set('sentTestEmail', false)
$.ajax $.ajax
url: '/admin/email_logs/test', url: '/admin/email_logs/test',
type: 'POST' type: 'POST'
data: data:
@ -14,4 +14,4 @@ window.Discourse.AdminEmailLogsController = Ember.ArrayController.extend Discour
success: => success: =>
@set('sentTestEmail', true) @set('sentTestEmail', true)
false false

View File

@ -20,11 +20,11 @@ window.Discourse.AdminSiteSettingsController = Ember.ArrayController.extend Disc
true true
).property('filter', 'content.@each', 'onlyOverridden') ).property('filter', 'content.@each', 'onlyOverridden')
resetDefault: (setting) -> resetDefault: (setting) ->
setting.set('value', setting.get('default')) setting.set('value', setting.get('default'))
setting.save() setting.save()
save: (setting) -> setting.save() save: (setting) -> setting.save()
cancel: (setting) -> setting.resetValue() cancel: (setting) -> setting.resetValue()

View File

@ -12,8 +12,8 @@ window.Discourse.AdminUsersListController = Ember.ArrayController.extend Discour
filterUsers: Discourse.debounce(-> filterUsers: Discourse.debounce(->
@refreshUsers() @refreshUsers()
,250).observes('username') ,250).observes('username')
orderChanged: (-> orderChanged: (->
@refreshUsers() @refreshUsers()
).observes('query') ).observes('query')

View File

@ -40,13 +40,13 @@ window.Discourse.AdminUser = Discourse.Model.extend
canBan: ( -> canBan: ( ->
!@admin && !@moderator !@admin && !@moderator
).property('admin','moderator') ).property('admin','moderator')
banDuration: (-> banDuration: (->
banned_at = Date.create(@banned_at) banned_at = Date.create(@banned_at)
banned_till = Date.create(@banned_till) banned_till = Date.create(@banned_till)
"#{banned_at.short()} - #{banned_till.short()}" "#{banned_at.short()} - #{banned_till.short()}"
).property('banned_till', 'banned_at') ).property('banned_till', 'banned_at')
ban: -> ban: ->
@ -64,7 +64,7 @@ window.Discourse.AdminUser = Discourse.Model.extend
error = Em.String.i18n('admin.user.ban_failed', error: "http: #{e.status} - #{e.body}") error = Em.String.i18n('admin.user.ban_failed', error: "http: #{e.status} - #{e.body}")
bootbox.alert error bootbox.alert error
return return
unban: -> unban: ->
$.ajax "/admin/users/#{@id}/unban", $.ajax "/admin/users/#{@id}/unban",
type: 'PUT' type: 'PUT'
@ -75,7 +75,7 @@ window.Discourse.AdminUser = Discourse.Model.extend
error = Em.String.i18n('admin.user.unban_failed', error: "http: #{e.status} - #{e.body}") error = Em.String.i18n('admin.user.unban_failed', error: "http: #{e.status} - #{e.body}")
bootbox.alert error bootbox.alert error
return return
impersonate: -> impersonate: ->
$.ajax "/admin/impersonate" $.ajax "/admin/impersonate"
type: 'POST' type: 'POST'

View File

@ -11,7 +11,7 @@ window.Discourse.EmailLog.reopenClass
$.ajax $.ajax
url: "/admin/email_logs.json" url: "/admin/email_logs.json"
data: {filter: filter} data: {filter: filter}
success: (logs) -> success: (logs) ->
logs.each (log) -> result.pushObject(Discourse.EmailLog.create(log)) logs.each (log) -> result.pushObject(Discourse.EmailLog.create(log))
result result

View File

@ -15,7 +15,7 @@ window.Discourse.FlaggedPost = Discourse.Post.extend
message: a.message message: a.message
r r
).property() ).property()
lastFlagged: (-> lastFlagged: (->
@post_actions[0].created_at @post_actions[0].created_at
).property() ).property()

View File

@ -45,7 +45,7 @@ window.Discourse.SiteCustomization = Discourse.Model.extend
data: data:
site_customization: data site_customization: data
type: if @id then 'PUT' else 'POST' type: if @id then 'PUT' else 'POST'
delete: -> delete: ->
return unless @id return unless @id
$.ajax $.ajax

View File

@ -23,19 +23,19 @@ window.Discourse.SiteSetting = Discourse.Model.extend Discourse.Presence,
save: -> save: ->
# Update the setting # Update the setting
$.ajax "/admin/site_settings/#{@get('setting')}", $.ajax "/admin/site_settings/#{@get('setting')}",
data: data:
value: @get('value') value: @get('value')
type: 'PUT' type: 'PUT'
success: => @set('originalValue', @get('value')) success: => @set('originalValue', @get('value'))
window.Discourse.SiteSetting.reopenClass window.Discourse.SiteSetting.reopenClass
findAll: -> findAll: ->
result = Em.A() result = Em.A()
$.get "/admin/site_settings", (settings) -> $.get "/admin/site_settings", (settings) ->
settings.each (s) -> settings.each (s) ->
s.originalValue = s.value s.originalValue = s.value
result.pushObject(Discourse.SiteSetting.create(s)) result.pushObject(Discourse.SiteSetting.create(s))
result result

View File

@ -1,2 +1,2 @@
Discourse.AdminCustomizeRoute = Discourse.Route.extend Discourse.AdminCustomizeRoute = Discourse.Route.extend
model: -> Discourse.SiteCustomization.findAll() model: -> Discourse.SiteCustomization.findAll()

View File

@ -1,2 +1,2 @@
Discourse.AdminEmailLogsRoute = Discourse.Route.extend Discourse.AdminEmailLogsRoute = Discourse.Route.extend
model: -> Discourse.EmailLog.findAll() model: -> Discourse.EmailLog.findAll()

View File

@ -3,4 +3,4 @@ Discourse.AdminFlagsActiveRoute = Discourse.Route.extend
setupController: (controller, model) -> setupController: (controller, model) ->
c = @controllerFor('adminFlags') c = @controllerFor('adminFlags')
c.set('content', model) c.set('content', model)
c.set('query', 'active') c.set('query', 'active')

View File

@ -3,4 +3,4 @@ Discourse.AdminFlagsOldRoute = Discourse.Route.extend
setupController: (controller, model) -> setupController: (controller, model) ->
c = @controllerFor('adminFlags') c = @controllerFor('adminFlags')
c.set('content', model) c.set('content', model)
c.set('query', 'old') c.set('query', 'old')

View File

@ -1,2 +1,2 @@
Discourse.AdminUserRoute = Discourse.Route.extend Discourse.AdminUserRoute = Discourse.Route.extend
model: (params) -> Discourse.AdminUser.find(params.username) model: (params) -> Discourse.AdminUser.find(params.username)

View File

@ -1,2 +1,2 @@
Discourse.AdminUsersListActiveRoute = Discourse.Route.extend Discourse.AdminUsersListActiveRoute = Discourse.Route.extend
setupController: (c) -> @controllerFor('adminUsersList').show('active') setupController: (c) -> @controllerFor('adminUsersList').show('active')

View File

@ -1,2 +1,2 @@
Discourse.AdminUsersListNewRoute = Discourse.Route.extend Discourse.AdminUsersListNewRoute = Discourse.Route.extend
setupController: (c) -> @controllerFor('adminUsersList').show('new') setupController: (c) -> @controllerFor('adminUsersList').show('new')

View File

@ -1,2 +1,2 @@
Discourse.AdminUsersListNewRoute = Discourse.Route.extend Discourse.AdminUsersListNewRoute = Discourse.Route.extend
setupController: (c) -> @controllerFor('adminUsersList').show('pending') setupController: (c) -> @controllerFor('adminUsersList').show('pending')

View File

@ -6,7 +6,7 @@ Discourse.AceEditorView = window.Discourse.View.extend
if @editor && !@skipContentChangeEvent if @editor && !@skipContentChangeEvent
@editor.getSession().setValue(@get('content')) @editor.getSession().setValue(@get('content'))
).observes('content') ).observes('content')
render: (buffer) -> render: (buffer) ->
buffer.push("<div class='ace'>") buffer.push("<div class='ace'>")
buffer.push(Handlebars.Utils.escapeExpression(@get('content'))) if @get('content') buffer.push(Handlebars.Utils.escapeExpression(@get('content'))) if @get('content')

View File

@ -10,7 +10,7 @@ Discourse.AdminCustomizeView = window.Discourse.View.extend
headerActive: (-> headerActive: (->
@get('selected') == 'header' @get('selected') == 'header'
).property('selected') ).property('selected')
stylesheetActive: (-> stylesheetActive: (->
@get('selected') == 'stylesheet' @get('selected') == 'stylesheet'
).property('selected') ).property('selected')
@ -26,7 +26,7 @@ Discourse.AdminCustomizeView = window.Discourse.View.extend
Mousetrap.bindGlobal ['meta+s', 'ctrl+s'], => Mousetrap.bindGlobal ['meta+s', 'ctrl+s'], =>
@get('controller').save() @get('controller').save()
return false return false
willDestroyElement: -> willDestroyElement: ->
Mousetrap.unbindGlobal('meta+s','ctrl+s') Mousetrap.unbindGlobal('meta+s','ctrl+s')

View File

@ -1,2 +1,2 @@
Discourse.AdminDashboardView = window.Discourse.View.extend Discourse.AdminDashboardView = window.Discourse.View.extend
templateName: 'admin/templates/dashboard' templateName: 'admin/templates/dashboard'

View File

@ -1,2 +1,2 @@
Discourse.AdminEmailLogsView = window.Discourse.View.extend Discourse.AdminEmailLogsView = window.Discourse.View.extend
templateName: 'admin/templates/email_logs' templateName: 'admin/templates/email_logs'

View File

@ -1,2 +1,2 @@
Discourse.AdminSiteSettingsView = window.Discourse.View.extend Discourse.AdminSiteSettingsView = window.Discourse.View.extend
templateName: 'admin/templates/site_settings' templateName: 'admin/templates/site_settings'

View File

@ -1,2 +1,2 @@
Discourse.AdminUserView = window.Discourse.View.extend Discourse.AdminUserView = window.Discourse.View.extend
templateName: 'admin/templates/user' templateName: 'admin/templates/user'

View File

@ -1,2 +1,2 @@
Discourse.AdminView = window.Discourse.View.extend Discourse.AdminView = window.Discourse.View.extend
templateName: 'admin/templates/admin' templateName: 'admin/templates/admin'

View File

@ -23,7 +23,7 @@ window.Discourse = Ember.Application.createWithMixins
title += "#{@get('title')} - " if @get('title') title += "#{@get('title')} - " if @get('title')
title += Discourse.SiteSettings.title title += Discourse.SiteSettings.title
$('title').text(title) $('title').text(title)
title = ("(*) " + title) if !@get('hasFocus') && @get('notify') title = ("(*) " + title) if !@get('hasFocus') && @get('notify')
# chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome # chrome bug workaround see: http://stackoverflow.com/questions/2952384/changing-the-window-title-when-focussing-the-window-doesnt-work-in-chrome
@ -43,12 +43,12 @@ window.Discourse = Ember.Application.createWithMixins
bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval bus.callbackInterval = Discourse.SiteSettings.anon_polling_interval
bus.enableLongPolling = false bus.enableLongPolling = false
user = @get('currentUser') user = @get('currentUser')
if user if user
bus.callbackInterval = Discourse.SiteSettings.polling_interval bus.callbackInterval = Discourse.SiteSettings.polling_interval
bus.enableLongPolling = true bus.enableLongPolling = true
if user.admin if user.admin
bus.subscribe "/flagged_counts", (data) -> bus.subscribe "/flagged_counts", (data) ->
user.set('site_flagged_posts_count', data.total) user.set('site_flagged_posts_count', data.total)
@ -90,13 +90,13 @@ window.Discourse = Ember.Application.createWithMixins
# Be wary of looking up the router. In this case, we have links in our # Be wary of looking up the router. In this case, we have links in our
# HTML, say form compiled markdown posts, that need to be routed. # HTML, say form compiled markdown posts, that need to be routed.
router = Discourse.__container__.lookup('router:main') router = Discourse.__container__.lookup('router:main')
router.router.updateURL(path) router.router.updateURL(path)
router.handleURL(path) router.handleURL(path)
# Scroll to the top if we're not replacing state # Scroll to the top if we're not replacing state
# The classes of buttons to show on a post # The classes of buttons to show on a post
postButtons: (-> postButtons: (->
@ -171,7 +171,7 @@ window.Discourse = Ember.Application.createWithMixins
before: (data,owner, args) -> before: (data,owner, args) ->
if owner if owner
window.probes.clear() window.probes.clear()
after: (data, owner, args) -> after: (data, owner, args) ->
if owner && data.time > 10 if owner && data.time > 10
f = (name,data) -> f = (name,data) ->
@ -187,7 +187,7 @@ window.Discourse = Ember.Application.createWithMixins
for n,v of window.probes for n,v of window.probes
continue if n == name || v.time < 1 continue if n == name || v.time < 1
ary.push(k: n, v: v) ary.push(k: n, v: v)
ary.sortBy((item) -> if item.v && item.v.time then -item.v.time else 0).each (item)-> ary.sortBy((item) -> if item.v && item.v.time then -item.v.time else 0).each (item)->
console.log output if output = f("#{item.k}", item.v) console.log output if output = f("#{item.k}", item.v)
console?.groupEnd?() console?.groupEnd?()
@ -219,9 +219,9 @@ window.Discourse = Ember.Application.createWithMixins
Discourse.MessageBus.start() Discourse.MessageBus.start()
Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus) Discourse.KeyValueStore.init("discourse_", Discourse.MessageBus)
Discourse.insertProbes() Discourse.insertProbes()
# subscribe to any site customizations that are loaded
# subscribe to any site customizations that are loaded
$('link.custom-css').each -> $('link.custom-css').each ->
split = @href.split("/") split = @href.split("/")
id = split[split.length-1].split(".css")[0] id = split[split.length-1].split(".css")[0]

View File

@ -19,7 +19,7 @@
me = @ me = @
div = null div = null
# input is handled differently # input is handled differently
isInput = @[0].tagName == "INPUT" isInput = @[0].tagName == "INPUT"
inputSelectedItems = [] inputSelectedItems = []
@ -98,7 +98,7 @@
div.css(left: "-1000px") div.css(left: "-1000px")
me.parent().append(div) me.parent().append(div)
mePos = me.position() mePos = me.position()
borderTop = parseInt(me.css('border-top-width')) || 0 borderTop = parseInt(me.css('border-top-width')) || 0
@ -143,11 +143,11 @@
$(@).keypress (e) -> $(@).keypress (e) ->
if !options.key if !options.key
return return
# keep hunting backwards till you hit a # keep hunting backwards till you hit a
if e.which == options.key.charCodeAt(0) if e.which == options.key.charCodeAt(0)
caretPosition = Discourse.Utilities.caretPosition(me[0]) caretPosition = Discourse.Utilities.caretPosition(me[0])
@ -165,11 +165,11 @@
return if e.which == 16 return if e.which == 16
if completeStart == null && e.which == 8 && options.key #backspace if completeStart == null && e.which == 8 && options.key #backspace
c = Discourse.Utilities.caretPosition(me[0]) c = Discourse.Utilities.caretPosition(me[0])
next = me[0].value[c] next = me[0].value[c]
nextIsGood = next == undefined || /\s/.test(next) nextIsGood = next == undefined || /\s/.test(next)
c-=1 c-=1
initial = c initial = c
@ -186,7 +186,7 @@
term = me[0].value.substring(c+1, initial) term = me[0].value.substring(c+1, initial)
options.dataSource term, updateAutoComplete options.dataSource term, updateAutoComplete
return true return true
prevIsGood = /[a-zA-Z\.]/.test(prev) prevIsGood = /[a-zA-Z\.]/.test(prev)
@ -250,6 +250,6 @@
term += "," unless e.which == 8 # backspace term += "," unless e.which == 8 # backspace
options.dataSource term, updateAutoComplete options.dataSource term, updateAutoComplete
return true return true
)(jQuery) )(jQuery)

View File

@ -17,7 +17,7 @@ Discourse.BBCode =
withArgs: withArgs:
"url": (_, href, title) -> "<a href=\"#{href}\">#{title}</a>" "url": (_, href, title) -> "<a href=\"#{href}\">#{title}</a>"
"email": (_, address, title) -> "<a href=\"mailto:#{address}\">#{title}</a>" "email": (_, address, title) -> "<a href=\"mailto:#{address}\">#{title}</a>"
"color": (_, color, content) -> "color": (_, color, content) ->
return content unless /^(\#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?)|(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)$/.test(color) return content unless /^(\#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?)|(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)$/.test(color)
"<span style=\"color: #{color}\">#{content}</span>" "<span style=\"color: #{color}\">#{content}</span>"
@ -28,10 +28,10 @@ Discourse.BBCode =
"i": (_, content) -> "<i>#{content}</i>" "i": (_, content) -> "<i>#{content}</i>"
"u": (_, content) -> "<u>#{content}</u>" "u": (_, content) -> "<u>#{content}</u>"
"s": (_, content) -> "<s>#{content}</s>" "s": (_, content) -> "<s>#{content}</s>"
"spoiler": (_, content) -> "<span style='background-color: #000'>#{content}</span>" "spoiler": (_, content) -> "<span style='background-color: #000'>#{content}</span>"
withArgs: withArgs:
"size": (_, size, content) -> "<span style=\"font-size: #{size}px\">#{content}</span>" "size": (_, size, content) -> "<span style=\"font-size: #{size}px\">#{content}</span>"
# For sane environments that support CSS # For sane environments that support CSS
default: default:
@ -58,10 +58,10 @@ Discourse.BBCode =
Object.keys Discourse.BBCode.replacers, (name, rules) -> Object.keys Discourse.BBCode.replacers, (name, rules) ->
parsed = result[name] = [] parsed = result[name] = []
Object.keys Object.merge(Discourse.BBCode.replacers.base.withoutArgs, rules.withoutArgs), (tag, val) -> Object.keys Object.merge(Discourse.BBCode.replacers.base.withoutArgs, rules.withoutArgs), (tag, val) ->
parsed.push(regexp: RegExp("\\[#{tag}\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val) parsed.push(regexp: RegExp("\\[#{tag}\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val)
Object.keys Object.merge(Discourse.BBCode.replacers.base.withArgs, rules.withArgs), (tag, val) -> Object.keys Object.merge(Discourse.BBCode.replacers.base.withArgs, rules.withArgs), (tag, val) ->
parsed.push(regexp: RegExp("\\[#{tag}=?(.+?)\\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val) parsed.push(regexp: RegExp("\\[#{tag}=?(.+?)\\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val)
@parsed = result @parsed = result

View File

@ -1,6 +1,6 @@
# caret position in textarea ... very hacky ... sorry # caret position in textarea ... very hacky ... sorry
(($) -> (($) ->
# http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea # http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
getCaret = (el) -> getCaret = (el) ->
if el.selectionStart if el.selectionStart
@ -15,7 +15,7 @@
rc.setEndPoint "EndToStart", re rc.setEndPoint "EndToStart", re
return rc.text.length return rc.text.length
0 0
clone = null clone = null
$.fn.caretPosition = (options) -> $.fn.caretPosition = (options) ->
@ -66,15 +66,15 @@
before = pos - 1 before = pos - 1
after = pos after = pos
insertSpaceAfterBefore = false insertSpaceAfterBefore = false
# if before and after are \n insert a space # if before and after are \n insert a space
insertSpaceAfterBefore = true if val[before] is "\n" and val[after] is "\n" insertSpaceAfterBefore = true if val[before] is "\n" and val[after] is "\n"
guard = (v) -> guard = (v) ->
buf = v.replace(/</g,"&lt;") buf = v.replace(/</g,"&lt;")
buf = buf.replace(/>/g,"&gt;") buf = buf.replace(/>/g,"&gt;")
buf = buf.replace(/[ ]/g, "&#x200b;&nbsp;&#x200b;") buf = buf.replace(/[ ]/g, "&#x200b;&nbsp;&#x200b;")
buf.replace(/\n/g,"<br />") buf.replace(/\n/g,"<br />")
makeCursor = (pos, klass, color) -> makeCursor = (pos, klass, color) ->
l = val.substring(pos, pos + 1) l = val.substring(pos, pos + 1)
@ -95,7 +95,7 @@
pos.left = pos.left + letter.width() if letter.hasClass("before") pos.left = pos.left + letter.width() if letter.hasClass("before")
pPos = p.offset() pPos = p.offset()
#clone.hide().remove() #clone.hide().remove()
left: pos.left - pPos.left left: pos.left - pPos.left
top: (pos.top - pPos.top) - clone.scrollTop() top: (pos.top - pPos.top) - clone.scrollTop()
) jQuery ) jQuery

View File

@ -1,4 +1,4 @@
# We use this object to keep track of click counts. # We use this object to keep track of click counts.
window.Discourse.ClickTrack = window.Discourse.ClickTrack =
# Pass the event of the click here and we'll do the magic! # Pass the event of the click here and we'll do the magic!
@ -28,7 +28,7 @@ window.Discourse.ClickTrack =
userId = $article.data('user-id') unless userId userId = $article.data('user-id') unless userId
ownLink = userId and (userId is Discourse.get('currentUser.id')) ownLink = userId and (userId is Discourse.get('currentUser.id'))
# Build a Redirect URL # Build a Redirect URL
trackingUrl = "/clicks/track?url=" + encodeURIComponent(href) trackingUrl = "/clicks/track?url=" + encodeURIComponent(href)
trackingUrl += "&post_id=" + encodeURI(postId) if postId and (not $a.data('ignore-post-id')) trackingUrl += "&post_id=" + encodeURI(postId) if postId and (not $a.data('ignore-post-id'))
@ -44,9 +44,9 @@ window.Discourse.ClickTrack =
# If they right clicked, change the destination href # If they right clicked, change the destination href
if e.which is 3 if e.which is 3
destination = if Discourse.SiteSettings.track_external_right_clicks then trackingUrl else href destination = if Discourse.SiteSettings.track_external_right_clicks then trackingUrl else href
$a.attr('href', destination) $a.attr('href', destination)
return true return true
# if they want to open in a new tab, do an AJAX request # if they want to open in a new tab, do an AJAX request
if (e.metaKey || e.ctrlKey || e.which is 2) if (e.metaKey || e.ctrlKey || e.which is 2)
$.get "/clicks/track", url: href, post_id: postId, topic_id: topicId, redirect: false $.get "/clicks/track", url: href, post_id: postId, topic_id: topicId, redirect: false

View File

@ -42,12 +42,12 @@
mousePosition = (e) -> mousePosition = (e) ->
x: e.clientX + document.documentElement.scrollLeft x: e.clientX + document.documentElement.scrollLeft
y: e.clientY + document.documentElement.scrollTop y: e.clientY + document.documentElement.scrollTop
$.fn.DivResizer = (opts) -> $.fn.DivResizer = (opts) ->
@each -> @each ->
div = $(this) div = $(this)
return if (div.hasClass("processed")) return if (div.hasClass("processed"))
div.addClass("processed") div.addClass("processed")
staticOffset = null staticOffset = null

View File

@ -44,10 +44,10 @@ class Discourse.Eyeline
return true unless markSeen return true unless markSeen
# If you hit the bottom we mark all the elements as seen. Otherwise, just the first one # If you hit the bottom we mark all the elements as seen. Otherwise, just the first one
unless atBottom unless atBottom
@trigger('saw', detail: $elem) @trigger('saw', detail: $elem)
@trigger('sawTop', detail: $elem) if i == 0 @trigger('sawTop', detail: $elem) if i == 0
return false return false
@trigger('sawTop', detail: $elem) if i == 0 @trigger('sawTop', detail: $elem) if i == 0
@ -56,9 +56,9 @@ class Discourse.Eyeline
# Call this when we know aren't loading any more elements. Mark the rest # Call this when we know aren't loading any more elements. Mark the rest
# as seen # as seen
flushRest: -> flushRest: ->
$(@selector).each (i, elem) => $(@selector).each (i, elem) =>
$elem = $(elem) $elem = $(elem)
@trigger('saw', detail: $elem) @trigger('saw', detail: $elem)
RSVP.EventTarget.mixin(Discourse.Eyeline.prototype) RSVP.EventTarget.mixin(Discourse.Eyeline.prototype)

View File

@ -4,7 +4,7 @@
window.Discourse.KeyValueStore = (-> window.Discourse.KeyValueStore = (->
initialized = false initialized = false
context = "" context = ""
init: (ctx,messageBus) -> init: (ctx,messageBus) ->
initialized = true initialized = true
context = ctx context = ctx
@ -17,7 +17,7 @@ window.Discourse.KeyValueStore = (->
localStorage.removeItem(k) if k.substring(0, context.length) == context localStorage.removeItem(k) if k.substring(0, context.length) == context
i-- i--
return true return true
remove: (key)-> remove: (key)->
localStorage.removeItem(context + key) localStorage.removeItem(context + key)

View File

@ -45,11 +45,11 @@ window.Discourse.MessageBus = ( ->
if callbacks.length == 0 if callbacks.length == 0
setTimeout poll, 500 setTimeout poll, 500
return return
data = {} data = {}
callbacks.each (c)-> callbacks.each (c)->
data[c.channel] = if c.last_id == undefined then -1 else c.last_id data[c.channel] = if c.last_id == undefined then -1 else c.last_id
gotData = false gotData = false
@longPoll = $.ajax "/message-bus/#{clientId}/poll?#{if isHidden() || !@enableLongPolling then "dlp=t" else ""}", @longPoll = $.ajax "/message-bus/#{clientId}/poll?#{if isHidden() || !@enableLongPolling then "dlp=t" else ""}",
@ -98,7 +98,7 @@ window.Discourse.MessageBus = ( ->
subscribe: (channel,func,lastId)-> subscribe: (channel,func,lastId)->
callbacks.push {channel:channel, func:func, last_id: lastId} callbacks.push {channel:channel, func:func, last_id: lastId}
@longPoll.abort() if @longPoll @longPoll.abort() if @longPoll
# Unsubscribe from a channel # Unsubscribe from a channel
unsubscribe: (channel) -> unsubscribe: (channel) ->
# TODO proper globbing # TODO proper globbing

View File

@ -9,7 +9,7 @@ window.Discourse.PagedownEditor = Ember.ContainerView.extend
@pushObject Em.View.create(elementId: 'wmd-button-bar') @pushObject Em.View.create(elementId: 'wmd-button-bar')
@pushObject Em.TextArea.create(valueBinding: 'parentView.value', elementId: 'wmd-input') @pushObject Em.TextArea.create(valueBinding: 'parentView.value', elementId: 'wmd-input')
@pushObject Em.View.createWithMixins Discourse.Presence, @pushObject Em.View.createWithMixins Discourse.Presence,
elementId: 'wmd-preview', elementId: 'wmd-preview',
classNameBindings: [':preview', 'hidden'] classNameBindings: [':preview', 'hidden']
hidden: (-> hidden: (->

View File

@ -76,7 +76,7 @@ window.Discourse.ScreenTrack = Ember.Object.extend
if (highestSeenByTopic[topicId] || 0) < @highestSeen if (highestSeenByTopic[topicId] || 0) < @highestSeen
highestSeenByTopic[topicId] = @highestSeen highestSeenByTopic[topicId] = @highestSeen
unless Object.isEmpty(newTimings) unless Object.isEmpty(newTimings)
$.ajax '/topics/timings' $.ajax '/topics/timings'
data: data:
@ -93,7 +93,7 @@ window.Discourse.ScreenTrack = Ember.Object.extend
@lastFlush = 0 @lastFlush = 0
tick: -> tick: ->
# If the user hasn't scrolled the browser in a long time, stop tracking time read # If the user hasn't scrolled the browser in a long time, stop tracking time read
sinceScrolled = new Date().getTime() - @lastScrolled sinceScrolled = new Date().getTime() - @lastScrolled
if sinceScrolled > @PAUSE_UNLESS_SCROLLED if sinceScrolled > @PAUSE_UNLESS_SCROLLED
@ -116,7 +116,7 @@ window.Discourse.ScreenTrack = Ember.Object.extend
Object.keys @timings, (id) => Object.keys @timings, (id) =>
$element = $(id) $element = $(id)
if ($element.length == 1) if ($element.length == 1)
elemTop = $element.offset().top elemTop = $element.offset().top
elemBottom = elemTop + $element.height() elemBottom = elemTop + $element.height()

View File

@ -1,4 +1,4 @@
# Helper object for syntax highlighting. Uses highlight.js which is loaded # Helper object for syntax highlighting. Uses highlight.js which is loaded
# on demand. # on demand.
window.Discourse.SyntaxHighlighting = window.Discourse.SyntaxHighlighting =

View File

@ -1,4 +1,4 @@
# CSS transitions are a PITA, often we need to queue some js after a transition, this helper ensures # CSS transitions are a PITA, often we need to queue some js after a transition, this helper ensures
# it happens after the transition # it happens after the transition
# #

View File

@ -24,8 +24,8 @@ window.Discourse.UserSearch =
limit = options.limit || 5 limit = options.limit || 5
throw "missing callback" unless callback throw "missing callback" unless callback
#TODO site setting for allowed regex in username ? #TODO site setting for allowed regex in username ?
if term.match(/[^a-zA-Z0-9\_\.]/) if term.match(/[^a-zA-Z0-9\_\.]/)
callback([]) callback([])
return true return true

View File

@ -25,9 +25,9 @@ Discourse.Utilities =
return "" unless username return "" unless username
size = Discourse.Utilities.translateSize(size) size = Discourse.Utilities.translateSize(size)
rawSize = (size * (window.devicePixelRatio || 1)).toFixed() rawSize = (size * (window.devicePixelRatio || 1)).toFixed()
return template.replace(/\{size\}/g, rawSize) if template return template.replace(/\{size\}/g, rawSize) if template
"/users/#{username.toLowerCase()}/avatar/#{rawSize}?__ws=#{encodeURIComponent(Discourse.BaseUrl || "")}" "/users/#{username.toLowerCase()}/avatar/#{rawSize}?__ws=#{encodeURIComponent(Discourse.BaseUrl || "")}"
avatarImg: (options)-> avatarImg: (options)->
@ -63,7 +63,7 @@ Discourse.Utilities =
caretPosition: (el) -> caretPosition: (el) ->
return el.selectionStart if el.selectionStart return el.selectionStart if el.selectionStart
if document.selection if document.selection
el.focus() el.focus()
r = document.selection.createRange() r = document.selection.createRange()
@ -121,7 +121,7 @@ Discourse.Utilities =
result = text.replace /^`{3}(?:(.*$)\n)?([\s\S]*?)^`{3}/gm, (wholeMatch,m1,m2) -> result = text.replace /^`{3}(?:(.*$)\n)?([\s\S]*?)^`{3}/gm, (wholeMatch,m1,m2) ->
escaped = Handlebars.Utils.escapeExpression(m2) escaped = Handlebars.Utils.escapeExpression(m2)
"<pre><code class='#{m1 || 'lang-auto'}'>#{escaped}</code></pre>" "<pre><code class='#{m1 || 'lang-auto'}'>#{escaped}</code></pre>"
converter.hooks.chain "postConversion", (text) -> converter.hooks.chain "postConversion", (text) ->
return "" unless text return "" unless text
# don't to mention voodoo in pres # don't to mention voodoo in pres

View File

@ -3,4 +3,4 @@ window.Discourse.ApplicationController = Ember.Controller.extend
needs: ['modal'] needs: ['modal']
showLogin: -> showLogin: ->
@get('controllers.modal')?.show(Discourse.LoginView.create()) @get('controllers.modal')?.show(Discourse.LoginView.create())

View File

@ -24,18 +24,18 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
, (error) => , (error) =>
composer.set('disableDrafts', false) composer.set('disableDrafts', false)
bootbox.alert error bootbox.alert error
saveDraft: -> saveDraft: ->
model = @get('content') model = @get('content')
model.saveDraft() if model model.saveDraft() if model
# Open the reply view # Open the reply view
# #
# opts: # opts:
# action - The action we're performing: edit, reply or createTopic # action - The action we're performing: edit, reply or createTopic
# post - The post we're replying to, if present # post - The post we're replying to, if present
# topic - The topic we're replying to, if present # topic - The topic we're replying to, if present
# quote - If we're opening a reply from a quote, the quote we're making # quote - If we're opening a reply from a quote, the quote we're making
# #
open: (opts={}) -> open: (opts={}) ->
opts.promise = promise = opts.promise || new RSVP.Promise opts.promise = promise = opts.promise || new RSVP.Promise
@ -51,7 +51,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
controller: @ controller: @
view.appendTo($('#main')) view.appendTo($('#main'))
@set('view', view) @set('view', view)
# the next runloop is too soon, need to get the control rendered and then # the next runloop is too soon, need to get the control rendered and then
# we need to change stuff, otherwise css animations don't kick in # we need to change stuff, otherwise css animations don't kick in
Em.run.next => Em.run.next =>
Em.run.next => Em.run.next =>
@ -87,7 +87,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
if opts.draft if opts.draft
composer = Discourse.Composer.loadDraft(opts.draftKey, opts.draftSequence, opts.draft) composer = Discourse.Composer.loadDraft(opts.draftKey, opts.draftSequence, opts.draft)
composer?.set('topic', opts.topic) composer?.set('topic', opts.topic)
composer = composer || Discourse.Composer.open(opts) composer = composer || Discourse.Composer.open(opts)
@set('content', composer) @set('content', composer)
@ -119,7 +119,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
else else
fail() if typeof fail == "function" fail() if typeof fail == "function"
else else
# it is possible there is some sort of crazy draft with no body ... just give up on it # it is possible there is some sort of crazy draft with no body ... just give up on it
@destroyDraft() @destroyDraft()
@close() @close()
success() if typeof success == "function" success() if typeof success == "function"
@ -133,7 +133,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
shrink: -> shrink: ->
if @get('content.reply') == @get('content.originalText') then @close() else @collapse() if @get('content.reply') == @get('content.originalText') then @close() else @collapse()
collapse: -> collapse: ->
@saveDraft() @saveDraft()
@set('content.composeState', Discourse.Composer.DRAFT) @set('content.composeState', Discourse.Composer.DRAFT)
@ -166,7 +166,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence
# ESC key hit # ESC key hit
hitEsc: -> hitEsc: ->
@shrink() if @get('content.composeState') == @OPEN @shrink() if @get('content.composeState') == @OPEN
showOptions: -> showOptions: ->
@get('controllers.modal')?.show(Discourse.ArchetypeOptionsModalView.create(archetype: @get('content.archetype'), metaData: @get('content.metaData'))) @get('controllers.modal')?.show(Discourse.ArchetypeOptionsModalView.create(archetype: @get('content.archetype'), metaData: @get('content.metaData')))

View File

@ -1 +1 @@
Discourse.Controller = Ember.Controller.extend(Discourse.Presence) Discourse.Controller = Ember.Controller.extend(Discourse.Presence)

View File

@ -4,4 +4,4 @@ Discourse.HeaderController = Ember.Controller.extend Discourse.Presence,
toggleStar: -> toggleStar: ->
@get('topic')?.toggleStar() @get('topic')?.toggleStar()
false false

View File

@ -14,7 +14,7 @@ Discourse.ListCategoriesController = Ember.ObjectController.extend Discourse.Pre
editCategory: (category) -> editCategory: (category) ->
@get('controllers.modal').show(Discourse.EditCategoryView.create(category: category)) @get('controllers.modal').show(Discourse.EditCategoryView.create(category: category))
false false
canEdit: (-> canEdit: (->
u = Discourse.get('currentUser') u = Discourse.get('currentUser')
u && u.admin u && u.admin

View File

@ -9,7 +9,7 @@ Discourse.ListTopicsController = Ember.ObjectController.extend
if previousChannel = @get('previousChannel') if previousChannel = @get('previousChannel')
Discourse.MessageBus.unsubscribe "/#{previousChannel}" Discourse.MessageBus.unsubscribe "/#{previousChannel}"
@set('previousChannel', null) @set('previousChannel', null)
filterMode = @get('controllers.list.filterMode') filterMode = @get('controllers.list.filterMode')
return unless filterMode return unless filterMode
@ -19,7 +19,7 @@ Discourse.ListTopicsController = Ember.ObjectController.extend
@set('previousChannel', channel) @set('previousChannel', channel)
).observes('controllers.list.filterMode') ).observes('controllers.list.filterMode')
draftLoaded: (-> draftLoaded: (->
draft = @get('content.draft') draft = @get('content.draft')
if(draft) if(draft)

View File

@ -36,7 +36,7 @@ Discourse.PreferencesController = Ember.ObjectController.extend Discourse.Presen
@get('content').save (result) => @get('content').save (result) =>
@set('saving', false) @set('saving', false)
if result if result
@set('content.bio_cooked', Discourse.Utilities.cook(@get('content.bio_raw'))) @set('content.bio_cooked', Discourse.Utilities.cook(@get('content.bio_raw')))
@set('saved', true) @set('saved', true)
else else
alert 'failed' alert 'failed'
@ -51,4 +51,4 @@ Discourse.PreferencesController = Ember.ObjectController.extend Discourse.Presen
@set('passwordProgress','(generating email)') @set('passwordProgress','(generating email)')
@get('content').changePassword (message)=> @get('content').changePassword (message)=>
@set('changePasswordProgress', false) @set('changePasswordProgress', false)
@set('passwordProgress', "(#{message})") @set('passwordProgress', "(#{message})")

View File

@ -29,7 +29,7 @@ Discourse.PreferencesEmailController = Ember.ObjectController.extend Discourse.P
@set('saving', true) @set('saving', true)
@get('content').changeEmail(@get('newEmail')).then => @get('content').changeEmail(@get('newEmail')).then =>
@set('success', true) @set('success', true)
, => , =>
# Error # Error
@set('error', true) @set('error', true)
@set('saving', false) @set('saving', false)

View File

@ -34,7 +34,7 @@ Discourse.PreferencesUsernameController = Ember.ObjectController.extend Discours
@set('saving', true) @set('saving', true)
@get('content').changeUsername(@get('newUsername')).then => @get('content').changeUsername(@get('newUsername')).then =>
window.location = "/users/#{@get('newUsername').toLowerCase()}/preferences" window.location = "/users/#{@get('newUsername').toLowerCase()}/preferences"
, => , =>
# Error # Error
@set('error', true) @set('error', true)
@set('saving', false) @set('saving', false)

View File

@ -20,7 +20,7 @@ Discourse.QuoteButtonController = Discourse.Controller.extend
selectText: (e) -> selectText: (e) ->
return unless Discourse.get('currentUser') return unless Discourse.get('currentUser')
return unless @get('controllers.topic.content.can_create_post') return unless @get('controllers.topic.content.can_create_post')
selectedText = Discourse.Utilities.selectedText() selectedText = Discourse.Utilities.selectedText()
return if @get('buffer') == selectedText return if @get('buffer') == selectedText
return if @get('lastSelected') == selectedText return if @get('lastSelected') == selectedText
@ -51,20 +51,20 @@ Discourse.QuoteButtonController = Discourse.Controller.extend
post: post post: post
action: Discourse.Composer.REPLY action: Discourse.Composer.REPLY
draftKey: @get('post.topic.draft_key') draftKey: @get('post.topic.draft_key')
# If the composer is associated with a different post, we don't change it. # If the composer is associated with a different post, we don't change it.
if composerPost = composerController.get('content.post') if composerPost = composerController.get('content.post')
composerOpts.post = composerPost if (composerPost.get('id') != @get('post.id')) composerOpts.post = composerPost if (composerPost.get('id') != @get('post.id'))
buffer = @get('buffer') buffer = @get('buffer')
quotedText = Discourse.BBCode.buildQuoteBBCode(post, buffer) quotedText = Discourse.BBCode.buildQuoteBBCode(post, buffer)
if composerController.wouldLoseChanges() if composerController.wouldLoseChanges()
composerController.appendText(quotedText) composerController.appendText(quotedText)
else else
composerController.open(composerOpts).then => composerController.open(composerOpts).then =>
composerController.appendText(quotedText) composerController.appendText(quotedText)
@set('buffer', '') @set('buffer', '')
false false

View File

@ -8,7 +8,7 @@ Discourse.ShareController = Ember.Controller.extend
@set('link', url) @set('link', url)
false false
# Close the share controller # Close the share controller
close: -> close: ->
@set('link', '') @set('link', '')
false false

View File

@ -9,13 +9,13 @@ Discourse.StaticController = Ember.Controller.extend
$preloaded = $("noscript[data-path=\"#{path}\"]") $preloaded = $("noscript[data-path=\"#{path}\"]")
if $preloaded.length if $preloaded.length
text = $preloaded.text()# + "" text = $preloaded.text()# + ""
text = text.replace(/\<header[\s\S]*\<\/header\>/, '') text = text.replace(/\<header[\s\S]*\<\/header\>/, '')
@set('content', text) @set('content', text)
else else
jQuery.ajax jQuery.ajax
url: "#{path}.json" url: "#{path}.json"
success: (result) => success: (result) =>
@set('content', result) @set('content', result)
Discourse.StaticController.reopenClass(pages: ['faq', 'tos', 'privacy']) Discourse.StaticController.reopenClass(pages: ['faq', 'tos', 'privacy'])

View File

@ -3,4 +3,4 @@ Discourse.TopicAdminMenuController = Ember.ObjectController.extend
visible: false visible: false
show: -> @set('visible', true) show: -> @set('visible', true)
hide: -> @set('visible', false) hide: -> @set('visible', false)

View File

@ -49,7 +49,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
unless p.get('can_delete') unless p.get('can_delete')
canDelete = false canDelete = false
return false return false
canDelete canDelete
).property('selectedPosts') ).property('selectedPosts')
@ -58,7 +58,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
unless @get('multiSelect') unless @get('multiSelect')
if posts = @get('content.posts') if posts = @get('content.posts')
posts.forEach (p) -> p.set('selected', false) posts.forEach (p) -> p.set('selected', false)
).observes('multiSelect') ).observes('multiSelect')
hideProgress: (-> hideProgress: (->
@ -95,7 +95,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
replyAsNewTopic: (post) -> replyAsNewTopic: (post) ->
composerController = @get('controllers.composer') composerController = @get('controllers.composer')
#TODO shut down topic draft cleanly if it exists ... #TODO shut down topic draft cleanly if it exists ...
promise = composerController.open promise = composerController.open
action: Discourse.Composer.CREATE_TOPIC action: Discourse.Composer.CREATE_TOPIC
draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY draftKey: Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY
@ -103,7 +103,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
postUrl = "#{location.protocol}//#{location.host}#{post.get('url')}" postUrl = "#{location.protocol}//#{location.host}#{post.get('url')}"
postLink = "[#{@get('title')}](#{postUrl})" postLink = "[#{@get('title')}](#{postUrl})"
promise.then -> promise.then ->
Discourse.Post.loadQuote(post.get('id')).then (q) -> Discourse.Post.loadQuote(post.get('id')).then (q) ->
composerController.appendText("#{Em.String.i18n("post.continue_discussion", postLink: postLink)}\n\n#{q}") composerController.appendText("#{Em.String.i18n("post.continue_discussion", postLink: postLink)}\n\n#{q}")
# Topic related # Topic related
@ -145,14 +145,14 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
return unless topic return unless topic
posts = topic.get('posts') posts = topic.get('posts')
return unless posts return unless posts
posts.clear() posts.clear()
@set('content.loaded', false) @set('content.loaded', false)
Discourse.Topic.find(@get('content.id'), @get('postFilters')).then (result) => Discourse.Topic.find(@get('content.id'), @get('postFilters')).then (result) =>
first = result.posts.first() first = result.posts.first()
@set('currentPost', first.post_number) if first @set('currentPost', first.post_number) if first
$('#topic-progress .solid').data('progress', false) $('#topic-progress .solid').data('progress', false)
result.posts.each (p) => result.posts.each (p) =>
posts.pushObject(Discourse.Post.create(p, topic)) posts.pushObject(Discourse.Post.create(p, topic))
@set('content.loaded', true) @set('content.loaded', true)
@ -163,7 +163,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
@get('content').delete => @get('content').delete =>
@set('message', "The topic has been deleted") @set('message', "The topic has been deleted")
@set('loaded', false) @set('loaded', false)
toggleVisibility: -> toggleVisibility: ->
@get('content').toggleStatus('visible') @get('content').toggleStatus('visible')
@ -226,7 +226,7 @@ Discourse.TopicController = Ember.ObjectController.extend Discourse.Presence,
quoteController = @get('controllers.quoteButton') quoteController = @get('controllers.quoteButton')
quotedText = Discourse.BBCode.buildQuoteBBCode(quoteController.get('post'), quoteController.get('buffer')) quotedText = Discourse.BBCode.buildQuoteBBCode(quoteController.get('post'), quoteController.get('buffer'))
quoteController.set('buffer', '') quoteController.set('buffer', '')
if (composerController.get('content.topic.id') == post.get('topic.id') and composerController.get('content.action') == Discourse.Composer.REPLY) if (composerController.get('content.topic.id') == post.get('topic.id') and composerController.get('content.action') == Discourse.Composer.REPLY)
composerController.set('content.post', post) composerController.set('content.post', post)
composerController.set('content.composeState', Discourse.Composer.OPEN) composerController.set('content.composeState', Discourse.Composer.OPEN)

View File

@ -2,4 +2,4 @@ Discourse.UserInvitedController = Ember.ObjectController.extend
rescind: (invite) -> rescind: (invite) ->
invite.rescind() invite.rescind()
false false

View File

@ -2,7 +2,7 @@ Discourse.UserPrivateMessagesController = Ember.ObjectController.extend
editPreferences: -> editPreferences: ->
Discourse.routeTo("/users/#{@get('content.username_lower')}/preferences") Discourse.routeTo("/users/#{@get('content.username_lower')}/preferences")
composePrivateMessage: -> composePrivateMessage: ->
composerController = Discourse.get('router.composerController') composerController = Discourse.get('router.composerController')
composerController.open composerController.open

View File

@ -1,16 +1,16 @@
Handlebars.registerHelper 'breakUp', (property, options) -> Handlebars.registerHelper 'breakUp', (property, options) ->
prop = Ember.Handlebars.get(this, property, options) prop = Ember.Handlebars.get(this, property, options)
return "" unless prop return "" unless prop
tokens = prop.match(RegExp(".{1,14}",'g')) tokens = prop.match(RegExp(".{1,14}",'g'))
return prop if tokens.length == 1 return prop if tokens.length == 1
result = "" result = ""
tokens.each (token, index) -> tokens.each (token, index) ->
result += token result += token
if token.indexOf(' ') == -1 and (index < tokens.length - 1) if token.indexOf(' ') == -1 and (index < tokens.length - 1)
result += "- " result += "- "
result result
@ -28,9 +28,9 @@ Handlebars.registerHelper 'categoryLink', (property, options) ->
Handlebars.registerHelper 'titledLinkTo', (name, object) -> Handlebars.registerHelper 'titledLinkTo', (name, object) ->
options = [].slice.call(arguments, -1)[0] options = [].slice.call(arguments, -1)[0]
if options.hash.titleKey if options.hash.titleKey
options.hash.title = Em.String.i18n(options.hash.titleKey) options.hash.title = Em.String.i18n(options.hash.titleKey)
if arguments.length is 3 if arguments.length is 3
Ember.Handlebars.helpers.linkTo.call(this, name, object, options) Ember.Handlebars.helpers.linkTo.call(this, name, object, options)
@ -43,7 +43,7 @@ Handlebars.registerHelper 'shortenUrl', (property, options) ->
# Remove trailing slash if it's a top level URL # Remove trailing slash if it's a top level URL
url = url.replace(/\/$/, '') if url.match(/\//g).length == 3 url = url.replace(/\/$/, '') if url.match(/\//g).length == 3
url = url.replace(/^https?:\/\//, '') url = url.replace(/^https?:\/\//, '')
url = url.replace(/^www\./, '') url = url.replace(/^www\./, '')
url.truncate(80) url.truncate(80)
@ -68,7 +68,7 @@ Handlebars.registerHelper 'avatar', (user, options) ->
title: Em.get(user, 'title') || Em.get(user, 'description') title: Em.get(user, 'title') || Em.get(user, 'description')
avatarTemplate: Ember.get(user, 'avatar_template') || options.hash.avatarTemplate avatarTemplate: Ember.get(user, 'avatar_template') || options.hash.avatarTemplate
) )
Handlebars.registerHelper 'unboundDate', (property, options) -> Handlebars.registerHelper 'unboundDate', (property, options) ->
dt = new Date(Ember.Handlebars.get(this, property, options)) dt = new Date(Ember.Handlebars.get(this, property, options))
month = Date.SugarMethods.getLocale.method().months[12 + dt.getMonth()] month = Date.SugarMethods.getLocale.method().months[12 + dt.getMonth()]
@ -104,7 +104,7 @@ Handlebars.registerHelper 'date', (property, options) ->
val = Ember.Handlebars.get(this, property, options) val = Ember.Handlebars.get(this, property, options)
return new Handlebars.SafeString("&mdash;") unless val return new Handlebars.SafeString("&mdash;") unless val
dt = new Date(val) dt = new Date(val)
fullReadable = dt.format("{d} {Mon}, {yyyy} {hh}:{mm}") fullReadable = dt.format("{d} {Mon}, {yyyy} {hh}:{mm}")
@ -122,7 +122,7 @@ Handlebars.registerHelper 'date', (property, options) ->
return "" unless humanized return "" unless humanized
displayDate = humanized displayDate = humanized
displayDate = displayDate.replace(' ago', '') unless leaveAgo displayDate = displayDate.replace(' ago', '') unless leaveAgo
new Handlebars.SafeString("<span class='date' title='#{fullReadable}'>#{displayDate}</span>") new Handlebars.SafeString("<span class='date' title='#{fullReadable}'>#{displayDate}</span>")

View File

@ -9,7 +9,7 @@ window.Discourse.Presence = Em.Mixin.create
when "string" when "string"
return prop.trim().isBlank() return prop.trim().isBlank()
when "object" when "object"
return Object.isEmpty(prop) return Object.isEmpty(prop)
false false
present: (name) -> not @blank(name) present: (name) -> not @blank(name)

View File

@ -29,7 +29,7 @@ window.Discourse.ActionSummary = Em.Object.extend Discourse.Presence,
@set('can_undo', true) @set('can_undo', true)
#TODO: mark all other flag types as acted #TODO: mark all other flag types as acted
# Add ourselves to the users who liked it if present # Add ourselves to the users who liked it if present
@users.pushObject(Discourse.get('currentUser')) if @present('users') @users.pushObject(Discourse.get('currentUser')) if @present('users')
@ -45,7 +45,7 @@ window.Discourse.ActionSummary = Em.Object.extend Discourse.Presence,
@removeAction() @removeAction()
errors = jQuery.parseJSON(error.responseText).errors errors = jQuery.parseJSON(error.responseText).errors
bootbox.alert(errors[0]) bootbox.alert(errors[0])
# Undo this action # Undo this action
undo: -> undo: ->
@ -57,7 +57,7 @@ window.Discourse.ActionSummary = Em.Object.extend Discourse.Presence,
type: 'DELETE' type: 'DELETE'
data: data:
post_action_type_id: @get('id') post_action_type_id: @get('id')
clearFlags: -> clearFlags: ->
$.ajax $.ajax
url: "/post_actions/clear_flags" url: "/post_actions/clear_flags"

View File

@ -18,14 +18,14 @@ window.Discourse.Composer = Discourse.Model.extend
val = (Discourse.KeyValueStore.get('composer.showPreview') or 'true') val = (Discourse.KeyValueStore.get('composer.showPreview') or 'true')
@set('showPreview', val is 'true') @set('showPreview', val is 'true')
@set 'archetypeId', Discourse.get('site.default_archetype') @set 'archetypeId', Discourse.get('site.default_archetype')
archetypesBinding: 'Discourse.site.archetypes' archetypesBinding: 'Discourse.site.archetypes'
creatingTopic: (-> @get('action') == CREATE_TOPIC ).property('action') creatingTopic: (-> @get('action') == CREATE_TOPIC ).property('action')
creatingPrivateMessage: (-> @get('action') == PRIVATE_MESSAGE ).property('action') creatingPrivateMessage: (-> @get('action') == PRIVATE_MESSAGE ).property('action')
editingPost: (-> @get('action') == EDIT).property('action') editingPost: (-> @get('action') == EDIT).property('action')
viewOpen: (-> @get('composeState') == OPEN ).property('composeState') viewOpen: (-> @get('composeState') == OPEN ).property('composeState')
archetype: (-> archetype: (->
@get('archetypes').findProperty('id', @get('archetypeId')) @get('archetypes').findProperty('id', @get('archetypeId'))
).property('archetypeId') ).property('archetypeId')
@ -44,7 +44,7 @@ window.Discourse.Composer = Discourse.Model.extend
togglePreview: -> togglePreview: ->
@toggleProperty('showPreview') @toggleProperty('showPreview')
Discourse.KeyValueStore.set(key: 'showPreview', value: @get('showPreview')) Discourse.KeyValueStore.set(key: 'showPreview', value: @get('showPreview'))
# Import a quote from the post # Import a quote from the post
importQuote: -> importQuote: ->
post = @get('post') post = @get('post')
@ -95,7 +95,7 @@ window.Discourse.Composer = Discourse.Model.extend
).property('showPreview') ).property('showPreview')
hidePreview: (-> not @get('showPreview') ).property('showPreview') hidePreview: (-> not @get('showPreview') ).property('showPreview')
# Whether to disable the post button # Whether to disable the post button
cantSubmitPost: (-> cantSubmitPost: (->
@ -113,7 +113,7 @@ window.Discourse.Composer = Discourse.Model.extend
false false
).property('reply', 'title', 'creatingTopic', 'loading') ).property('reply', 'title', 'creatingTopic', 'loading')
# The text for the save button # The text for the save button
saveText: (-> saveText: (->
switch @get('action') switch @get('action')
@ -129,20 +129,20 @@ window.Discourse.Composer = Discourse.Model.extend
return Em.empty(Em.keys(@get('metaData'))) return Em.empty(Em.keys(@get('metaData')))
).property('metaData') ).property('metaData')
wouldLoseChanges: ()-> wouldLoseChanges: ()->
@get('reply') != @get('originalText') # TODO title check as well @get('reply') != @get('originalText') # TODO title check as well
# Open a composer # Open a composer
# #
# opts: # opts:
# action - The action we're performing: edit, reply or createTopic # action - The action we're performing: edit, reply or createTopic
# post - The post we're replying to, if present # post - The post we're replying to, if present
# topic - The topic we're replying to, if present # topic - The topic we're replying to, if present
# quote - If we're opening a reply from a quote, the quote we're making # quote - If we're opening a reply from a quote, the quote we're making
# #
open: (opts={}) -> open: (opts={}) ->
@set('loading', false) @set('loading', false)
topicId = opts.topic.get('id') if opts.topic topicId = opts.topic.get('id') if opts.topic
@ -151,7 +151,7 @@ window.Discourse.Composer = Discourse.Model.extend
opts.tested = true opts.tested = true
@cancel(=> @open(opts)) @cancel(=> @open(opts))
return return
@set 'draftKey', opts.draftKey @set 'draftKey', opts.draftKey
@set 'draftSequence', opts.draftSequence @set 'draftSequence', opts.draftSequence
throw 'draft key is required' unless opts.draftKey throw 'draft key is required' unless opts.draftKey
@ -177,7 +177,7 @@ window.Discourse.Composer = Discourse.Model.extend
Discourse.Post.load opts.postId, (result) => Discourse.Post.load opts.postId, (result) =>
@set('post', result) @set('post', result)
@set('loading', false) @set('loading', false)
# If we are editing a post, load it. # If we are editing a post, load it.
if opts.action == EDIT and opts.post if opts.action == EDIT and opts.post
@set 'title', @get('topic.title') @set 'title', @get('topic.title')
@ -186,7 +186,7 @@ window.Discourse.Composer = Discourse.Model.extend
@set 'reply', result.get('raw') @set 'reply', result.get('raw')
@set('originalText', @get('reply')) @set('originalText', @get('reply'))
@set('loading', false) @set('loading', false)
if opts.title if opts.title
@set('title', opts.title) @set('title', opts.title)
if opts.draft if opts.draft
@ -196,7 +196,7 @@ window.Discourse.Composer = Discourse.Model.extend
false false
save: (opts)-> save: (opts)->
if @get('editingPost') if @get('editingPost')
@editPost(opts) @editPost(opts)
@ -230,7 +230,7 @@ window.Discourse.Composer = Discourse.Model.extend
postNumber = post.get('post_number') postNumber = post.get('post_number')
posts.each (p,i)-> posts.each (p,i)->
idx = i if p.get('post_number') == postNumber idx = i if p.get('post_number') == postNumber
if idx > -1 if idx > -1
savedPost.set('topic', @get('topic')) savedPost.set('topic', @get('topic'))
posts.replace(idx, 1, [savedPost]) posts.replace(idx, 1, [savedPost])
@ -244,7 +244,7 @@ window.Discourse.Composer = Discourse.Model.extend
@set('composeState', OPEN) @set('composeState', OPEN)
promise promise
# Create a new Post # Create a new Post
createPost: (opts)-> createPost: (opts)->
@ -274,9 +274,9 @@ window.Discourse.Composer = Discourse.Model.extend
addedToStream = false addedToStream = false
# If we're in a topic, we can append the post instantly. # If we're in a topic, we can append the post instantly.
if topic if topic
# Increase the reply count # Increase the reply count
if post if post
post.set('reply_count', (post.get('reply_count') || 0) + 1) post.set('reply_count', (post.get('reply_count') || 0) + 1)
@ -299,17 +299,17 @@ window.Discourse.Composer = Discourse.Model.extend
# If we're near the end of the topic, load new posts # If we're near the end of the topic, load new posts
lastPost = topic.posts.last() lastPost = topic.posts.last()
if lastPost if lastPost
diff = topic.get('highest_post_number') - lastPost.get('post_number') diff = topic.get('highest_post_number') - lastPost.get('post_number')
# If the new post is within a threshold of the end of the topic, # If the new post is within a threshold of the end of the topic,
# add it and scroll there instead of adding the link. # add it and scroll there instead of adding the link.
if diff < 5 if diff < 5
createdPost.set('scrollToAfterInsert', createdPost.get('post_number')) createdPost.set('scrollToAfterInsert', createdPost.get('post_number'))
topic.pushPosts([createdPost]) topic.pushPosts([createdPost])
addedToStream = true addedToStream = true
# Save callback # Save callback
createdPost.save (result) => createdPost.save (result) =>
addedPost = false addedPost = false
@ -323,7 +323,7 @@ window.Discourse.Composer = Discourse.Model.extend
# We created a new topic, let's show it. # We created a new topic, let's show it.
@set('composeState', CLOSED) @set('composeState', CLOSED)
saving = false saving = false
@set('reply', '') @set('reply', '')
@set('createdPost', createdPost) @set('createdPost', createdPost)
@ -354,7 +354,7 @@ window.Discourse.Composer = Discourse.Model.extend
archetypeId: @get('archetypeId') archetypeId: @get('archetypeId')
metaData: @get('metaData') metaData: @get('metaData')
usernames: @get('targetUsernames') usernames: @get('targetUsernames')
@set('draftStatus', Em.String.i18n('composer.saving_draft_tip')) @set('draftStatus', Em.String.i18n('composer.saving_draft_tip'))
Discourse.Draft.save(@get('draftKey'), @get('draftSequence'), data) Discourse.Draft.save(@get('draftKey'), @get('draftSequence'), data)
.then( .then(
@ -417,6 +417,6 @@ Discourse.Composer.reopenClass
EDIT: EDIT EDIT: EDIT
# Draft key # Draft key
REPLY_AS_NEW_TOPIC_KEY: REPLY_AS_NEW_TOPIC_KEY REPLY_AS_NEW_TOPIC_KEY: REPLY_AS_NEW_TOPIC_KEY

View File

@ -18,11 +18,11 @@ Discourse.Draft.reopenClass
success: (data) => success: (data) =>
promise.resolve(data) promise.resolve(data)
promise promise
getLocal: (key, current) -> getLocal: (key, current) ->
return current return current
# disabling for now to see if it helps with siracusa issue. # disabling for now to see if it helps with siracusa issue.
local = Discourse.KeyValueStore.get("draft_#{key}") local = Discourse.KeyValueStore.get("draft_#{key}")
if !current || (local && local.length > current.length) if !current || (local && local.length > current.length)
@ -46,6 +46,6 @@ Discourse.Draft.reopenClass
# Discourse.KeyValueStore.set(key: "draft_#{key}", value: data) # Discourse.KeyValueStore.set(key: "draft_#{key}", value: data)
promise.reject() promise.reject()
promise promise

View File

@ -1,10 +1,10 @@
window.Discourse.InviteList = Discourse.Model.extend Discourse.Presence, window.Discourse.InviteList = Discourse.Model.extend Discourse.Presence,
empty: (-> empty: (->
return @blank('pending') and @blank('redeemed') return @blank('pending') and @blank('redeemed')
).property('pending.@each', 'redeemed.@each') ).property('pending.@each', 'redeemed.@each')
window.Discourse.InviteList.reopenClass window.Discourse.InviteList.reopenClass
findInvitedBy: (user) -> findInvitedBy: (user) ->
promise = new RSVP.Promise() promise = new RSVP.Promise()
@ -16,4 +16,4 @@ window.Discourse.InviteList.reopenClass
invitedList.redeemed = (invitedList.redeemed.map (i) -> Discourse.Invite.create(i)) if invitedList.redeemed invitedList.redeemed = (invitedList.redeemed.map (i) -> Discourse.Invite.create(i)) if invitedList.redeemed
invitedList.user = user invitedList.user = user
promise.resolve(Discourse.InviteList.create(invitedList)) promise.resolve(Discourse.InviteList.create(invitedList))
promise promise

View File

@ -5,7 +5,7 @@ Discourse.Mention = (->
cache = (name, valid) -> cache = (name, valid) ->
localCache[name] = valid localCache[name] = valid
return return
lookupCache = (name) -> lookupCache = (name) ->
localCache[name] localCache[name]
@ -19,7 +19,7 @@ Discourse.Mention = (->
cache(name,r.valid) cache(name,r.valid)
callback(r.valid) callback(r.valid)
return true return true
load = (e) -> load = (e) ->
$elem = $(e) $elem = $(e)
return if $elem.data('mention-tested') return if $elem.data('mention-tested')
@ -38,4 +38,4 @@ Discourse.Mention = (->
lookup: lookup lookup: lookup
lookupCache: lookupCache lookupCache: lookupCache
)() )()

View File

@ -20,9 +20,9 @@ window.Discourse.Model = Ember.Object.extend
col = @get(k) col = @get(k)
v.each (obj) -> col.pushObject(builder.create(obj)) v.each (obj) -> col.pushObject(builder.create(obj))
else else
@set(k, v) @set(k, v)
window.Discourse.Model.reopenClass window.Discourse.Model.reopenClass
# Given an array of values, return them in a hash # Given an array of values, return them in a hash
@ -33,4 +33,4 @@ window.Discourse.Model.reopenClass
collection.each (c) -> collection.each (c) ->
obj = klass.create(c) obj = klass.create(c)
retval[c.id] = obj retval[c.id] = obj
retval retval

View File

@ -27,11 +27,11 @@ Discourse.NavItem.reopenClass
countSummary = opts["countSummary"] countSummary = opts["countSummary"]
loggedOn = opts["loggedOn"] loggedOn = opts["loggedOn"]
hasCategories = opts["hasCategories"] hasCategories = opts["hasCategories"]
split = text.split(",") split = text.split(",")
name = split[0] name = split[0]
testName = name.split("/")[0] # to handle category ... testName = name.split("/")[0] # to handle category ...
return null if !loggedOn && !validAnon.contains(testName) return null if !loggedOn && !validAnon.contains(testName)
return null if !hasCategories && testName == "categories" return null if !hasCategories && testName == "categories"

View File

@ -20,7 +20,7 @@ window.Discourse.Notification = Discourse.Model.extend Discourse.Presence,
window.Discourse.Notification.reopenClass window.Discourse.Notification.reopenClass
create: (obj) -> create: (obj) ->
result = @_super(obj) result = @_super(obj)
result.set('data', Em.Object.create(obj.data)) if obj.data result.set('data', Em.Object.create(obj.data)) if obj.data

View File

@ -1,5 +1,5 @@
Discourse.Onebox = (-> Discourse.Onebox = (->
# for now it only stores in a var, in future we can change it so it uses localStorage, # for now it only stores in a var, in future we can change it so it uses localStorage,
# trouble with localStorage is that expire semantics need some thinking # trouble with localStorage is that expire semantics need some thinking
#cacheKey = "__onebox__" #cacheKey = "__onebox__"
@ -9,9 +9,9 @@ Discourse.Onebox = (->
localCache[url] = contents localCache[url] = contents
#if localStorage && localStorage.setItem #if localStorage && localStorage.setItem
# localStorage.setItme # localStorage.setItme
null null
lookupCache = (url) -> lookupCache = (url) ->
localCache[url] localCache[url]
@ -25,7 +25,7 @@ Discourse.Onebox = (->
cache(url,html) cache(url,html)
callback(html) callback(html)
return true return true
load = (e, refresh=false) -> load = (e, refresh=false) ->
url = e.href url = e.href
@ -45,4 +45,4 @@ Discourse.Onebox = (->
lookup: lookup lookup: lookup
lookupCache: lookupCache lookupCache: lookupCache
)() )()

View File

@ -52,14 +52,14 @@ Discourse.Topic = Discourse.Model.extend Discourse.Presence,
).observes('posts.@each','posts') ).observes('posts.@each','posts')
# The amount of new posts to display. It might be different than what the server # The amount of new posts to display. It might be different than what the server
# tells us if we are still asynchronously flushing our "recently read" data. # tells us if we are still asynchronously flushing our "recently read" data.
# So take what the browser has seen into consideration. # So take what the browser has seen into consideration.
displayNewPosts: (-> displayNewPosts: (->
if highestSeen = Discourse.get('highestSeenByTopic')[@get('id')] if highestSeen = Discourse.get('highestSeenByTopic')[@get('id')]
delta = highestSeen - @get('last_read_post_number') delta = highestSeen - @get('last_read_post_number')
if delta > 0 if delta > 0
result = (@get('new_posts') - delta) result = (@get('new_posts') - delta)
result = 0 if result < 0 result = 0 if result < 0
return result return result
@ -78,9 +78,9 @@ Discourse.Topic = Discourse.Model.extend Discourse.Presence,
ageCold: (-> ageCold: (->
return unless lastPost = @get('last_posted_at') return unless lastPost = @get('last_posted_at')
return unless createdAt = @get('created_at') return unless createdAt = @get('created_at')
daysSinceEpoch = (dt) -> daysSinceEpoch = (dt) ->
# 1000 * 60 * 60 * 24 = days since epoch # 1000 * 60 * 60 * 24 = days since epoch
dt.getTime() / 86400000 dt.getTime() / 86400000
# Show heat on age # Show heat on age
@ -169,12 +169,12 @@ Discourse.Topic = Discourse.Model.extend Discourse.Presence,
bestOf: opts.bestOf bestOf: opts.bestOf
trackVisit: opts.trackVisit trackVisit: opts.trackVisit
.then (result) => .then (result) =>
# If loading the topic succeeded... # If loading the topic succeeded...
# Update the slug if different # Update the slug if different
@set('slug', result.slug) if result.slug @set('slug', result.slug) if result.slug
# If we want to scroll to a post that doesn't exist, just pop them to the closest # If we want to scroll to a post that doesn't exist, just pop them to the closest
# one instead. This is likely happening due to a deleted post. # one instead. This is likely happening due to a deleted post.
opts.nearPost = parseInt(opts.nearPost) opts.nearPost = parseInt(opts.nearPost)
closestPostNumber = 0 closestPostNumber = 0
@ -189,7 +189,7 @@ Discourse.Topic = Discourse.Model.extend Discourse.Presence,
@get('participants').clear() if @get('participants') @get('participants').clear() if @get('participants')
@set('suggested_topics', Em.A()) if result.suggested_topics @set('suggested_topics', Em.A()) if result.suggested_topics
@mergeAttributes result, suggested_topics: Discourse.Topic @mergeAttributes result, suggested_topics: Discourse.Topic
@set('posts', Em.A()) @set('posts', Em.A())
@ -237,7 +237,7 @@ Discourse.Topic = Discourse.Model.extend Discourse.Presence,
url: "/t/#{@get('id')}/notifications" url: "/t/#{@get('id')}/notifications"
type: 'POST' type: 'POST'
data: {notification_level: v} data: {notification_level: v}
# use to add post to topics protecting from dupes # use to add post to topics protecting from dupes
pushPosts: (newPosts)-> pushPosts: (newPosts)->
map = {} map = {}
@ -257,13 +257,13 @@ window.Discourse.Topic.reopenClass
MUTE: 0 MUTE: 0
# Load a topic, but accepts a set of filters # Load a topic, but accepts a set of filters
# #
# options: # options:
# onLoad - the callback after the topic is loaded # onLoad - the callback after the topic is loaded
find: (topicId, opts) -> find: (topicId, opts) ->
url = "/t/#{topicId}" url = "/t/#{topicId}"
url += "/#{opts.nearPost}" if opts.nearPost url += "/#{opts.nearPost}" if opts.nearPost
data = {} data = {}
data.posts_after = opts.postsAfter if opts.postsAfter data.posts_after = opts.postsAfter if opts.postsAfter
data.posts_before = opts.postsBefore if opts.postsBefore data.posts_before = opts.postsBefore if opts.postsBefore
@ -276,7 +276,7 @@ window.Discourse.Topic.reopenClass
# Add the best of filter if we have it # Add the best of filter if we have it
data.best_of = true if opts.bestOf == true data.best_of = true if opts.bestOf == true
# Check the preload store. If not, load it via JSON # Check the preload store. If not, load it via JSON
promise = new RSVP.Promise() promise = new RSVP.Promise()
PreloadStore.get("topic_#{topicId}", -> jQuery.getJSON url + ".json", data).then (result) -> PreloadStore.get("topic_#{topicId}", -> jQuery.getJSON url + ".json", data).then (result) ->
@ -286,7 +286,7 @@ window.Discourse.Topic.reopenClass
, (result) -> promise.reject(result) , (result) -> promise.reject(result)
promise promise
# Create a topic from posts # Create a topic from posts
movePosts: (topicId, title, postIds) -> movePosts: (topicId, title, postIds) ->
$.ajax "/t/#{topicId}/move-posts", $.ajax "/t/#{topicId}/move-posts",

View File

@ -2,7 +2,7 @@ window.Discourse.TopicList = Discourse.Model.extend
emptyListTip: (-> emptyListTip: (->
return null unless @get('loaded') return null unless @get('loaded')
t = @get('topics') t = @get('topics')
return null if t && t.length > 0 return null if t && t.length > 0
@ -32,7 +32,7 @@ window.Discourse.TopicList = Discourse.Model.extend
insert: (json) -> insert: (json) ->
newTopic = Discourse.TopicList.decodeTopic(json) newTopic = Discourse.TopicList.decodeTopic(json)
# New Topics are always unseen # New Topics are always unseen
newTopic.set('unseen', true) newTopic.set('unseen', true)
@ -75,7 +75,7 @@ window.Discourse.TopicList.reopenClass
url = "/#{filter}.json" url = "/#{filter}.json"
if menuItem.filters && menuItem.filters.length > 0 if menuItem.filters && menuItem.filters.length > 0
url += "?exclude_category=" + menuItem.filters[0].substring(1) url += "?exclude_category=" + menuItem.filters[0].substring(1)
if list = Discourse.get('transient.topicsList') if list = Discourse.get('transient.topicsList')
if (list.get('filter') is filter) and window.location.pathname.indexOf('more') > 0 if (list.get('filter') is filter) and window.location.pathname.indexOf('more') > 0
promise = new RSVP.Promise() promise = new RSVP.Promise()

View File

@ -26,11 +26,11 @@ window.Discourse.User = Discourse.Model.extend Discourse.Presence,
username_lower:(-> username_lower:(->
@get('username').toLowerCase() @get('username').toLowerCase()
).property('username') ).property('username')
trustLevel: (-> trustLevel: (->
Discourse.get('site.trust_levels').findProperty('id', @get('trust_level')) Discourse.get('site.trust_levels').findProperty('id', @get('trust_level'))
).property('trust_level') ).property('trust_level')
changeUsername: (newUsername) -> changeUsername: (newUsername) ->
$.ajax $.ajax
url: "/users/#{@get('username_lower')}/preferences/username" url: "/users/#{@get('username_lower')}/preferences/username"
@ -41,7 +41,7 @@ window.Discourse.User = Discourse.Model.extend Discourse.Presence,
$.ajax $.ajax
url: "/users/#{@get('username_lower')}/preferences/email" url: "/users/#{@get('username_lower')}/preferences/email"
type: 'PUT' type: 'PUT'
data: {email: email} data: {email: email}
copy: (deep) -> copy: (deep) ->
Discourse.User.create(@getProperties(Ember.keys(@))) Discourse.User.create(@getProperties(Ember.keys(@)))
@ -164,7 +164,7 @@ window.Discourse.User.reopenClass
if s.action_type == k if s.action_type == k
g[k] = s g[k] = s
s.count = c s.count = c
g[s.action_type] = s unless found g[s.action_type] = s unless found
stats.map((s)-> stats.map((s)->

View File

@ -2,4 +2,4 @@ window.Discourse.ApplicationRoute = Discourse.Route.extend
setupController: (controller) -> setupController: (controller) ->
Discourse.set('site', Discourse.Site.create(PreloadStore.getStatic('site'))) Discourse.set('site', Discourse.Site.create(PreloadStore.getStatic('site')))
currentUser = PreloadStore.getStatic('currentUser') currentUser = PreloadStore.getStatic('currentUser')
Discourse.set('currentUser', Discourse.User.create(currentUser)) if currentUser Discourse.set('currentUser', Discourse.User.create(currentUser)) if currentUser

View File

@ -6,7 +6,7 @@ Discourse.buildRoutes ->
@route 'bestOf', path: '/best_of' @route 'bestOf', path: '/best_of'
# Generate static page routes # Generate static page routes
router = @ router = @
Discourse.StaticController.pages.forEach (p) -> router.route(p, path: "/#{p}") Discourse.StaticController.pages.forEach (p) -> router.route(p, path: "/#{p}")
@route 'faq', path: '/faq' @route 'faq', path: '/faq'
@ -24,10 +24,10 @@ Discourse.buildRoutes ->
router.route 'categories', path: '/categories' router.route 'categories', path: '/categories'
router.route 'category', path: '/category/:slug/more' router.route 'category', path: '/category/:slug/more'
router.route 'category', path: '/category/:slug' router.route 'category', path: '/category/:slug'
@resource 'user', path: '/users/:username', -> @resource 'user', path: '/users/:username', ->
@route 'activity', path: '/' @route 'activity', path: '/'
@resource 'preferences', path: '/preferences', -> @resource 'preferences', path: '/preferences', ->
@route 'username', path: '/username' @route 'username', path: '/username'
@route 'email', path: '/email' @route 'email', path: '/email'

View File

@ -18,8 +18,8 @@ window.Discourse.Route = Em.Route.extend
# Hide any searches # Hide any searches
if search = router.get('searchController') if search = router.get('searchController')
search.close() search.close()
# get rid of "save as draft stuff" # get rid of "save as draft stuff"
composerController = Discourse.get('router.composerController') composerController = Discourse.get('router.composerController')
composerController.closeIfCollapsed() if composerController composerController.closeIfCollapsed() if composerController

View File

@ -19,5 +19,5 @@ window.Discourse.FilteredListRoute = Discourse.Route.extend
Discourse.ListController.filters.each (filter) -> Discourse.ListController.filters.each (filter) ->
window.Discourse["List#{filter.capitalize()}Route"] = Discourse.FilteredListRoute.extend(filter: filter) window.Discourse["List#{filter.capitalize()}Route"] = Discourse.FilteredListRoute.extend(filter: filter)

View File

@ -10,4 +10,4 @@ window.Discourse.ListCategoriesRoute = Discourse.Route.extend
@render 'listCategories', into: 'list', outlet: 'listView', controller: 'listCategories' @render 'listCategories', into: 'list', outlet: 'listView', controller: 'listCategories'
listController.set('canCreateCategory', categoryList.get('can_create_category')) listController.set('canCreateCategory', categoryList.get('can_create_category'))
listController.set('category', null) listController.set('category', null)
@controllerFor('listCategories').set('content', categoryList) @controllerFor('listCategories').set('content', categoryList)

View File

@ -7,4 +7,4 @@ window.Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend
listController.load("category/#{model.slug}").then (topicList) => listController.load("category/#{model.slug}").then (topicList) =>
listController.set('canCreateTopic', topicList.get('can_create_topic')) listController.set('canCreateTopic', topicList.get('can_create_topic'))
listController.set('category', Discourse.Category.create(name: model.slug)) listController.set('category', Discourse.Category.create(name: model.slug))
@controllerFor('listTopics').set('content', topicList) @controllerFor('listTopics').set('content', topicList)

View File

@ -2,4 +2,4 @@ window.Discourse.PreferencesEmailRoute = Discourse.Route.extend
renderTemplate: -> renderTemplate: ->
@render into: 'user', outlet: 'userOutlet' @render into: 'user', outlet: 'userOutlet'
setupController: (controller) -> setupController: (controller) ->
controller.set('content', @controllerFor('user').get('content')) controller.set('content', @controllerFor('user').get('content'))

View File

@ -3,4 +3,4 @@ window.Discourse.PreferencesRoute = Discourse.Route.extend
@render 'preferences', into: 'user', outlet: 'userOutlet', controller: 'preferences' @render 'preferences', into: 'user', outlet: 'userOutlet', controller: 'preferences'
setupController: (controller) -> setupController: (controller) ->
controller.set('content', @controllerFor('user').get('content')) controller.set('content', @controllerFor('user').get('content'))

View File

@ -4,4 +4,4 @@ window.Discourse.PreferencesUsernameRoute = Discourse.Route.extend
setupController: (controller) -> setupController: (controller) ->
user = @controllerFor('user').get('content') user = @controllerFor('user').get('content')
controller.set('content', user) controller.set('content', user)
controller.set('newUsername', user.get('username')) controller.set('newUsername', user.get('username'))

View File

@ -1,4 +1,4 @@
Discourse.StaticController.pages.forEach (page) -> Discourse.StaticController.pages.forEach (page) ->
window.Discourse["#{page.capitalize()}Route"] = Discourse.Route.extend window.Discourse["#{page.capitalize()}Route"] = Discourse.Route.extend
renderTemplate: -> @render 'static' renderTemplate: -> @render 'static'
setupController: -> @controllerFor('static').loadPath("/#{page}") setupController: -> @controllerFor('static').loadPath("/#{page}")

View File

@ -4,4 +4,4 @@ window.Discourse.TopicFromParamsRoute = Discourse.Route.extend
params.trackVisit = true params.trackVisit = true
topicController = @controllerFor('topic') topicController = @controllerFor('topic')
topicController.cancelFilter() topicController.cancelFilter()
@modelFor('topic').loadPosts(params) @modelFor('topic').loadPosts(params)

View File

@ -18,4 +18,4 @@ window.Discourse.TopicRoute = Discourse.Route.extend
setupController: (controller, model) -> setupController: (controller, model) ->
controller.set('showExtraHeaderInfo', false) controller.set('showExtraHeaderInfo', false)
headerController = @controllerFor('header') headerController = @controllerFor('header')
headerController?.set('topic', model) headerController?.set('topic', model)

View File

@ -5,4 +5,4 @@ window.Discourse.UserActivityRoute = Discourse.Route.extend
setupController: (controller) -> setupController: (controller) ->
userController = @controllerFor('user') userController = @controllerFor('user')
userController.set('filter', null) # clear filter userController.set('filter', null) # clear filter
controller.set('content', userController.get('content')) controller.set('content', userController.get('content'))

View File

@ -4,4 +4,4 @@ window.Discourse.UserInvitedRoute = Discourse.Route.extend
setupController: (controller) -> setupController: (controller) ->
Discourse.InviteList.findInvitedBy(@controllerFor('user').get('content')).then (invited) => Discourse.InviteList.findInvitedBy(@controllerFor('user').get('content')).then (invited) =>
controller.set('content', invited) controller.set('content', invited)

View File

@ -5,7 +5,7 @@ window.Discourse.UserPrivateMessagesRoute = Discourse.Route.extend
user = @controllerFor('user').get('content') user = @controllerFor('user').get('content')
controller.set('content', user) controller.set('content', user)
user.filterStream(13) user.filterStream(13)
Discourse.Draft.get('new_private_message').then (data)=> Discourse.Draft.get('new_private_message').then (data)=>
if data.draft if data.draft
@controllerFor('composer').open @controllerFor('composer').open

View File

@ -1,3 +1,3 @@
window.Discourse.UserRoute = Discourse.Route.extend window.Discourse.UserRoute = Discourse.Route.extend
model: (params) -> Discourse.User.find(params.username) model: (params) -> Discourse.User.find(params.username)
serialize: (params) -> username: Em.get(params, 'username').toLowerCase() serialize: (params) -> username: Em.get(params, 'username').toLowerCase()

View File

@ -1,3 +1,3 @@
window.Discourse.ArchetypeOptionsModalView = window.Discourse.ModalBodyView.extend window.Discourse.ArchetypeOptionsModalView = window.Discourse.ModalBodyView.extend
templateName: 'modal/archetype_options' templateName: 'modal/archetype_options'
title: Em.String.i18n('topic.options') title: Em.String.i18n('topic.options')

View File

@ -1,7 +1,7 @@
Discourse.AutoSizedTextView = Ember.View.extend Discourse.AutoSizedTextView = Ember.View.extend
render: (buffer)-> render: (buffer)->
null null
didInsertElement: (e) -> didInsertElement: (e) ->
me = @$() me = @$()
me.text(@get('content')) me.text(@get('content'))
@ -13,6 +13,6 @@ Discourse.AutoSizedTextView = Ember.View.extend
lh -=1 lh -=1
me.css("font-size", "#{fontSize}px") me.css("font-size", "#{fontSize}px")
me.css("line-height", "#{lh}px") me.css("line-height", "#{lh}px")

View File

@ -5,4 +5,4 @@ window.Discourse.ComboboxViewCategory = Discourse.ComboboxView.extend
template: (text, templateData) -> template: (text, templateData) ->
return text unless templateData.color return text unless templateData.color
"<span class='badge-category' style='background-color: ##{templateData.color}'>#{text}</span>" "<span class='badge-category' style='background-color: ##{templateData.color}'>#{text}</span>"

View File

@ -54,7 +54,7 @@ window.Discourse.ComposerView = window.Discourse.View.extend
willDestroyElement: -> willDestroyElement: ->
$('body').off 'keydown.composer' $('body').off 'keydown.composer'
resize: (-> resize: (->
# this still needs to wait on animations, need a clean way to do that # this still needs to wait on animations, need a clean way to do that
Em.run.next null, => Em.run.next null, =>
@ -91,13 +91,13 @@ window.Discourse.ComposerView = window.Discourse.View.extend
initEditor: -> initEditor: ->
# not quite right, need a callback to pass in, meaning this gets called once, # not quite right, need a callback to pass in, meaning this gets called once,
# but if you start replying to another topic it will get the avatars wrong # but if you start replying to another topic it will get the avatars wrong
@wmdInput = $wmdInput = $('#wmd-input') @wmdInput = $wmdInput = $('#wmd-input')
return if $wmdInput.length == 0 || $wmdInput.data('init') == true return if $wmdInput.length == 0 || $wmdInput.data('init') == true
Discourse.ComposerView.trigger("initWmdEditor") Discourse.ComposerView.trigger("initWmdEditor")
template = Handlebars.compile("<div class='autocomplete'> template = Handlebars.compile("<div class='autocomplete'>
<ul> <ul>
{{#each options}} {{#each options}}
@ -152,7 +152,7 @@ window.Discourse.ComposerView = window.Discourse.View.extend
@editor.hooks.onPreviewRefresh = => @afterRender() @editor.hooks.onPreviewRefresh = => @afterRender()
@editor.run() @editor.run()
@set('editor', @editor) @set('editor', @editor)
@loadingChanged() @loadingChanged()
saveDraft = Discourse.debounce((=> @get('controller').saveDraft()),2000) saveDraft = Discourse.debounce((=> @get('controller').saveDraft()),2000)
@ -165,7 +165,7 @@ window.Discourse.ComposerView = window.Discourse.View.extend
saveDraft() saveDraft()
return true return true
# In case it's still bound somehow # In case it's still bound somehow
$uploadTarget.fileupload('destroy') $uploadTarget.fileupload('destroy')
# Add the upload action # Add the upload action
@ -200,13 +200,13 @@ window.Discourse.ComposerView = window.Discourse.View.extend
@set('loadingImage', false) @set('loadingImage', false)
# I hate to use Em.run.later, but I don't think there's a way of waiting for a CSS transition # I hate to use Em.run.later, but I don't think there's a way of waiting for a CSS transition
# to finish. # to finish.
Em.run.later($, (=> Em.run.later($, (=>
replyTitle = $('#reply-title') replyTitle = $('#reply-title')
@resize() @resize()
if replyTitle.length if replyTitle.length
replyTitle.putCursorAtEnd() replyTitle.putCursorAtEnd()
else else
@ -242,7 +242,7 @@ Discourse.NotifyingTextArea = Ember.TextArea.extend
placeholder: (-> placeholder: (->
Em.String.i18n(@get('placeholderKey')) Em.String.i18n(@get('placeholderKey'))
).property('placeholderKey') ).property('placeholderKey')
didInsertElement: -> didInsertElement: ->
@get('parent').childDidInsertElement(@) @get('parent').childDidInsertElement(@)

View File

@ -7,7 +7,7 @@ window.Discourse.ExcerptCategoryView = Ember.View.extend
cat = @get('category') cat = @get('category')
cat.set('id', cat.get('slug')) cat.set('id', cat.get('slug'))
@get('controller.controllers.modal')?.showView(Discourse.EditCategoryView.create(category: cat)) @get('controller.controllers.modal')?.showView(Discourse.EditCategoryView.create(category: cat))
false false
deleteCategory: -> deleteCategory: ->
@ -16,8 +16,8 @@ window.Discourse.ExcerptCategoryView = Ember.View.extend
bootbox.confirm Em.String.i18n("category.delete_confirm"), (result) => bootbox.confirm Em.String.i18n("category.delete_confirm"), (result) =>
if result if result
@get('category').delete -> @get('category').delete ->
Discourse.get('appController').reloadSession -> Discourse.get('router').route("/categories") Discourse.get('appController').reloadSession -> Discourse.get('router').route("/categories")
false false
didInsertElement: -> didInsertElement: ->

View File

@ -6,7 +6,7 @@ window.Discourse.ExcerptUserView = Ember.View.extend
url = post.get("url") url = post.get("url")
username = post.get("username") username = post.get("username")
Discourse.router.route('/users/' + Discourse.currentUser.username.toLowerCase() + "/private-messages") Discourse.router.route('/users/' + Discourse.currentUser.username.toLowerCase() + "/private-messages")
# TODO figure out a way for it to open the composer cleanly AFTER the navigation happens. # TODO figure out a way for it to open the composer cleanly AFTER the navigation happens.
composerController = Discourse.get('router.composerController') composerController = Discourse.get('router.composerController')
composerController.open composerController.open

View File

@ -91,7 +91,7 @@ window.Discourse.ExcerptView = Ember.ContainerView.extend
didInsertElement: -> didInsertElement: ->
# lets disable this puppy for now, it looks unprofessional # lets disable this puppy for now, it looks unprofessional
return return
# We don't do hovering on touch devices # We don't do hovering on touch devices
@ -120,7 +120,7 @@ window.Discourse.ExcerptView = Ember.ContainerView.extend
topPosY = (pos.top - height) - margin topPosY = (pos.top - height) - margin
bottomPosY = (pos.top + margin) bottomPosY = (pos.top + margin)
# Switch to right if there's no room on top # Switch to right if there's no room on top
if positionText == 'top' if positionText == 'top'
positionText = 'bottom' if topPosY < 10 positionText = 'bottom' if topPosY < 10
@ -140,7 +140,7 @@ window.Discourse.ExcerptView = Ember.ContainerView.extend
if (pos.left || 0) <= 0 && (pos.top || 0) <= 0 if (pos.left || 0) <= 0 && (pos.top || 0) <= 0
# somehow, sometimes, we are trying to position stuff in weird spots, just skip it # somehow, sometimes, we are trying to position stuff in weird spots, just skip it
return return
@set('position', positionText) @set('position', positionText)
@set('desiredLocation', pos) @set('desiredLocation', pos)
@set('size', $target.data('excerpt-size')) @set('size', $target.data('excerpt-size'))
@ -150,5 +150,5 @@ window.Discourse.ExcerptView = Ember.ContainerView.extend
$('#main').on 'mouseleave', '.excerptable', (e) => $('#main').on 'mouseleave', '.excerptable', (e) =>
Em.run.cancel(@openTimer) Em.run.cancel(@openTimer)
@closeSoon() @closeSoon()

View File

@ -1,7 +1,7 @@
window.Discourse.FeaturedTopicsView = Ember.View.extend window.Discourse.FeaturedTopicsView = Ember.View.extend
templateName: 'featured_topics' templateName: 'featured_topics'
classNames: ['category-list-item'] classNames: ['category-list-item']
init: -> init: ->
@._super() @._super()
@set('context', @get('content')) @set('context', @get('content'))

View File

@ -9,13 +9,13 @@ window.Discourse.FlagView = Ember.View.extend
@set('isCustomFlag', action.is_custom_flag) @set('isCustomFlag', action.is_custom_flag)
Em.run.next -> $("#radio_#{action.name_key}").prop('checked', 'true') Em.run.next -> $("#radio_#{action.name_key}").prop('checked', 'true')
false false
createFlag: -> createFlag: ->
actionType = Discourse.get("site").postActionTypeById(@get('postActionTypeId')) actionType = Discourse.get("site").postActionTypeById(@get('postActionTypeId'))
@get("post.actionByName.#{actionType.get('name_key')}")?.act(message: @get('customFlagMessage')) @get("post.actionByName.#{actionType.get('name_key')}")?.act(message: @get('customFlagMessage'))
$('#discourse-modal').modal('hide') $('#discourse-modal').modal('hide')
false false
customPlaceholder: (-> customPlaceholder: (->
Em.String.i18n("flagging.custom_placeholder") Em.String.i18n("flagging.custom_placeholder")
).property() ).property()

View File

@ -7,7 +7,7 @@ window.Discourse.HeaderView = Ember.View.extend
currentUserBinding: 'Discourse.currentUser' currentUserBinding: 'Discourse.currentUser'
categoriesBinding: 'site.categories' categoriesBinding: 'site.categories'
topicBinding: 'Discourse.router.topicController.content' topicBinding: 'Discourse.router.topicController.content'
showDropdown: ($target) -> showDropdown: ($target) ->
elementId = $target.data('dropdown') || $target.data('notifications') elementId = $target.data('dropdown') || $target.data('notifications')
$dropdown = $("##{elementId}") $dropdown = $("##{elementId}")
@ -31,7 +31,7 @@ window.Discourse.HeaderView = Ember.View.extend
$html.on 'click.d-dropdown touchstart.d-dropdown', (e) => $html.on 'click.d-dropdown touchstart.d-dropdown', (e) =>
return true if $(e.target).closest('.d-dropdown').length > 0 return true if $(e.target).closest('.d-dropdown').length > 0
hideDropdown() hideDropdown()
$html.data('hide-dropdown', hideDropdown) $html.data('hide-dropdown', hideDropdown)
false false
@ -65,7 +65,7 @@ window.Discourse.HeaderView = Ember.View.extend
if @dockedHeader if @dockedHeader
$('body').removeClass('docked') $('body').removeClass('docked')
@dockedHeader = false @dockedHeader = false
willDestroyElement: -> willDestroyElement: ->
$(window).unbind 'scroll.discourse-dock' $(window).unbind 'scroll.discourse-dock'
@ -75,7 +75,7 @@ window.Discourse.HeaderView = Ember.View.extend
didInsertElement: -> didInsertElement: ->
@.$('a[data-dropdown]').on 'click touchstart', (e) => @showDropdown($(e.currentTarget)) @.$('a[data-dropdown]').on 'click touchstart', (e) => @showDropdown($(e.currentTarget))
@.$('a.unread-private-messages, a.unread-notifications, a[data-notifications]').on 'click touchstart', (e) => @showNotifications(e) @.$('a.unread-private-messages, a.unread-notifications, a[data-notifications]').on 'click touchstart', (e) => @showNotifications(e)
$(window).bind 'scroll.discourse-dock', => @examineDockHeader() $(window).bind 'scroll.discourse-dock', => @examineDockHeader()
$(document).bind 'touchmove.discourse-dock', => @examineDockHeader() $(document).bind 'touchmove.discourse-dock', => @examineDockHeader()
@examineDockHeader() @examineDockHeader()
@ -86,7 +86,7 @@ window.Discourse.HeaderView = Ember.View.extend
# Hide dropdowns # Hide dropdowns
if e.which == 27 if e.which == 27
@.$('li').removeClass('active') @.$('li').removeClass('active')
@.$('.d-dropdown').fadeOut('fast') @.$('.d-dropdown').fadeOut('fast')
if @get('editingTopic') if @get('editingTopic')
@finishedEdit() if e.which == 13 @finishedEdit() if e.which == 13

View File

@ -25,9 +25,9 @@ window.Discourse.HistoryView = Ember.View.extend
@get('originalPost').loadVersions (result) => @get('originalPost').loadVersions (result) =>
@set('loading', false) @set('loading', false)
@set('versionLeft', result.first()) @set('versionLeft', result.first())
@set('versionRight', result.last()) @set('versionRight', result.last())
@set('versions', result) @set('versions', result)

View File

@ -2,14 +2,14 @@ window.Discourse.ImageSelectorView = Ember.View.extend
templateName: 'image_selector' templateName: 'image_selector'
classNames: ['image-selector'] classNames: ['image-selector']
title: 'Insert Image' title: 'Insert Image'
init: -> init: ->
@._super() @._super()
@set('localSelected', true) @set('localSelected', true)
selectLocal: -> selectLocal: ->
@set('localSelected', true) @set('localSelected', true)
selectRemote: -> selectRemote: ->
@set('localSelected', false) @set('localSelected', false)
@ -26,6 +26,6 @@ window.Discourse.ImageSelectorView = Ember.View.extend
add: -> add: ->
@get('composer').addMarkdown("![image](#{$('#fileurl-input').val()})") @get('composer').addMarkdown("![image](#{$('#fileurl-input').val()})")
$('#discourse-modal').modal('hide') $('#discourse-modal').modal('hide')

View File

@ -17,4 +17,4 @@ Discourse.InputTipView = Ember.View.extend Discourse.Presence,
render: (buffer) -> render: (buffer) ->
if reason = @get('validation.reason') if reason = @get('validation.reason')
icon = if @get('good') then 'icon-ok' else 'icon-remove' icon = if @get('good') then 'icon-ok' else 'icon-remove'
buffer.push "<i class=\"icon #{icon}\"></i> #{reason}" buffer.push "<i class=\"icon #{icon}\"></i> #{reason}"

Some files were not shown because too many files have changed in this diff Show More