Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
b1bd3f12
Commit
b1bd3f12
authored
Mar 19, 2013
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix tests. added jquery.timeago.js
parent
124a5e27
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
247 additions
and
82 deletions
+247
-82
app/assets/javascripts/jquery.timeago.js
app/assets/javascripts/jquery.timeago.js
+181
-0
app/assets/javascripts/main.js.coffee
app/assets/javascripts/main.js.coffee
+2
-0
app/assets/javascripts/wall.js.coffee
app/assets/javascripts/wall.js.coffee
+16
-18
app/assets/stylesheets/sections/wall.scss
app/assets/stylesheets/sections/wall.scss
+8
-1
app/views/events/event/_note.html.haml
app/views/events/event/_note.html.haml
+1
-1
app/views/notify/note_wall_email.html.haml
app/views/notify/note_wall_email.html.haml
+1
-1
app/views/notify/note_wall_email.text.erb
app/views/notify/note_wall_email.text.erb
+1
-1
app/views/walls/show.html.haml
app/views/walls/show.html.haml
+23
-2
features/steps/shared/paths.rb
features/steps/shared/paths.rb
+1
-1
spec/features/gitlab_flavored_markdown_spec.rb
spec/features/gitlab_flavored_markdown_spec.rb
+1
-1
spec/features/notes_on_merge_requests_spec.rb
spec/features/notes_on_merge_requests_spec.rb
+2
-2
spec/features/notes_on_wall_spec.rb
spec/features/notes_on_wall_spec.rb
+8
-52
spec/features/security/project_access_spec.rb
spec/features/security/project_access_spec.rb
+1
-1
spec/mailers/notify_spec.rb
spec/mailers/notify_spec.rb
+1
-1
No files found.
app/assets/javascripts/jquery.timeago.js
0 → 100644
View file @
b1bd3f12
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.1.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(
function
(
factory
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
// AMD. Register as an anonymous module.
define
([
'
jquery
'
],
factory
);
}
else
{
// Browser globals
factory
(
jQuery
);
}
}(
function
(
$
)
{
$
.
timeago
=
function
(
timestamp
)
{
if
(
timestamp
instanceof
Date
)
{
return
inWords
(
timestamp
);
}
else
if
(
typeof
timestamp
===
"
string
"
)
{
return
inWords
(
$
.
timeago
.
parse
(
timestamp
));
}
else
if
(
typeof
timestamp
===
"
number
"
)
{
return
inWords
(
new
Date
(
timestamp
));
}
else
{
return
inWords
(
$
.
timeago
.
datetime
(
timestamp
));
}
};
var
$t
=
$
.
timeago
;
$
.
extend
(
$
.
timeago
,
{
settings
:
{
refreshMillis
:
60000
,
allowFuture
:
false
,
strings
:
{
prefixAgo
:
null
,
prefixFromNow
:
null
,
suffixAgo
:
"
ago
"
,
suffixFromNow
:
"
from now
"
,
seconds
:
"
less than a minute
"
,
minute
:
"
about a minute
"
,
minutes
:
"
%d minutes
"
,
hour
:
"
about an hour
"
,
hours
:
"
about %d hours
"
,
day
:
"
a day
"
,
days
:
"
%d days
"
,
month
:
"
about a month
"
,
months
:
"
%d months
"
,
year
:
"
about a year
"
,
years
:
"
%d years
"
,
wordSeparator
:
"
"
,
numbers
:
[]
}
},
inWords
:
function
(
distanceMillis
)
{
var
$l
=
this
.
settings
.
strings
;
var
prefix
=
$l
.
prefixAgo
;
var
suffix
=
$l
.
suffixAgo
;
if
(
this
.
settings
.
allowFuture
)
{
if
(
distanceMillis
<
0
)
{
prefix
=
$l
.
prefixFromNow
;
suffix
=
$l
.
suffixFromNow
;
}
}
var
seconds
=
Math
.
abs
(
distanceMillis
)
/
1000
;
var
minutes
=
seconds
/
60
;
var
hours
=
minutes
/
60
;
var
days
=
hours
/
24
;
var
years
=
days
/
365
;
function
substitute
(
stringOrFunction
,
number
)
{
var
string
=
$
.
isFunction
(
stringOrFunction
)
?
stringOrFunction
(
number
,
distanceMillis
)
:
stringOrFunction
;
var
value
=
(
$l
.
numbers
&&
$l
.
numbers
[
number
])
||
number
;
return
string
.
replace
(
/%d/i
,
value
);
}
var
words
=
seconds
<
45
&&
substitute
(
$l
.
seconds
,
Math
.
round
(
seconds
))
||
seconds
<
90
&&
substitute
(
$l
.
minute
,
1
)
||
minutes
<
45
&&
substitute
(
$l
.
minutes
,
Math
.
round
(
minutes
))
||
minutes
<
90
&&
substitute
(
$l
.
hour
,
1
)
||
hours
<
24
&&
substitute
(
$l
.
hours
,
Math
.
round
(
hours
))
||
hours
<
42
&&
substitute
(
$l
.
day
,
1
)
||
days
<
30
&&
substitute
(
$l
.
days
,
Math
.
round
(
days
))
||
days
<
45
&&
substitute
(
$l
.
month
,
1
)
||
days
<
365
&&
substitute
(
$l
.
months
,
Math
.
round
(
days
/
30
))
||
years
<
1.5
&&
substitute
(
$l
.
year
,
1
)
||
substitute
(
$l
.
years
,
Math
.
round
(
years
));
var
separator
=
$l
.
wordSeparator
||
""
;
if
(
$l
.
wordSeparator
===
undefined
)
{
separator
=
"
"
;
}
return
$
.
trim
([
prefix
,
words
,
suffix
].
join
(
separator
));
},
parse
:
function
(
iso8601
)
{
var
s
=
$
.
trim
(
iso8601
);
s
=
s
.
replace
(
/
\.\d
+/
,
""
);
// remove milliseconds
s
=
s
.
replace
(
/-/
,
"
/
"
).
replace
(
/-/
,
"
/
"
);
s
=
s
.
replace
(
/T/
,
"
"
).
replace
(
/Z/
,
"
UTC
"
);
s
=
s
.
replace
(
/
([\+\-]\d\d)\:?(\d\d)
/
,
"
$1$2
"
);
// -04:00 -> -0400
return
new
Date
(
s
);
},
datetime
:
function
(
elem
)
{
var
iso8601
=
$t
.
isTime
(
elem
)
?
$
(
elem
).
attr
(
"
datetime
"
)
:
$
(
elem
).
attr
(
"
title
"
);
return
$t
.
parse
(
iso8601
);
},
isTime
:
function
(
elem
)
{
// jQuery's `is()` doesn't play well with HTML5 in IE
return
$
(
elem
).
get
(
0
).
tagName
.
toLowerCase
()
===
"
time
"
;
// $(elem).is("time");
}
});
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var
functions
=
{
init
:
function
(){
var
refresh_el
=
$
.
proxy
(
refresh
,
this
);
refresh_el
();
var
$s
=
$t
.
settings
;
if
(
$s
.
refreshMillis
>
0
)
{
setInterval
(
refresh_el
,
$s
.
refreshMillis
);
}
},
update
:
function
(
time
){
$
(
this
).
data
(
'
timeago
'
,
{
datetime
:
$t
.
parse
(
time
)
});
refresh
.
apply
(
this
);
}
};
$
.
fn
.
timeago
=
function
(
action
,
options
)
{
var
fn
=
action
?
functions
[
action
]
:
functions
.
init
;
if
(
!
fn
){
throw
new
Error
(
"
Unknown function name '
"
+
action
+
"
' for timeago
"
);
}
// each over objects here and call the requested function
this
.
each
(
function
(){
fn
.
call
(
this
,
options
);
});
return
this
;
};
function
refresh
()
{
var
data
=
prepareData
(
this
);
if
(
!
isNaN
(
data
.
datetime
))
{
$
(
this
).
text
(
inWords
(
data
.
datetime
));
}
return
this
;
}
function
prepareData
(
element
)
{
element
=
$
(
element
);
if
(
!
element
.
data
(
"
timeago
"
))
{
element
.
data
(
"
timeago
"
,
{
datetime
:
$t
.
datetime
(
element
)
});
var
text
=
$
.
trim
(
element
.
text
());
if
(
text
.
length
>
0
&&
!
(
$t
.
isTime
(
element
)
&&
element
.
attr
(
"
title
"
)))
{
element
.
attr
(
"
title
"
,
text
);
}
}
return
element
.
data
(
"
timeago
"
);
}
function
inWords
(
date
)
{
return
$t
.
inWords
(
distance
(
date
));
}
function
distance
(
date
)
{
return
(
new
Date
().
getTime
()
-
date
.
getTime
());
}
// fix for IE6 suckage
document
.
createElement
(
"
abbr
"
);
document
.
createElement
(
"
time
"
);
}));
app/assets/javascripts/main.js.coffee
View file @
b1bd3f12
...
...
@@ -53,6 +53,8 @@ $ ->
$
(
'.trigger-submit'
).
on
'change'
,
->
$
(
@
).
parents
(
'form'
).
submit
()
$
(
"abbr.timeago"
).
timeago
()
# Flash
if
(
flash
=
$
(
".flash-container"
)).
length
>
0
flash
.
click
->
$
(
@
).
fadeOut
()
...
...
app/assets/javascripts/wall.js.coffee
View file @
b1bd3f12
...
...
@@ -30,24 +30,13 @@
Wall
.
note_ids
.
push
(
note
.
id
)
Wall
.
renderNote
(
note
)
Wall
.
scrollDown
()
$
(
"abbr.timeago"
).
timeago
()
complete
:
->
$
(
'.js-notes-busy'
).
removeClass
(
"loading"
)
beforeSend
:
->
$
(
'.js-notes-busy'
).
addClass
(
"loading"
)
renderNote
:
(
note
)
->
author
=
'<strong class="wall-author">'
+
note
.
author
.
name
+
'</strong>'
body
=
'<span class="wall-text">'
+
note
.
body
+
'</span>'
file
=
''
if
note
.
attachment
file
=
'<span class="wall-file"><a href="/files/note/'
+
note
.
id
+
'/'
+
note
.
attachment
+
'">'
+
note
.
attachment
+
'</a></span>'
html
=
'<li>'
+
author
+
body
+
file
+
'</li>'
$
(
'ul.notes'
).
append
(
html
)
initRefresh
:
->
setInterval
(
"Wall.refresh()"
,
10000
)
...
...
@@ -59,14 +48,9 @@
$
(
'body'
).
scrollTop
(
notes
.
height
())
initForm
:
->
form
=
$
(
'.
new_note
'
)
form
=
$
(
'.
wall-note-form
'
)
form
.
find
(
"#target_type"
).
val
(
'wall'
)
# remove unnecessary fields and buttons
form
.
find
(
"#note_line_code"
).
remove
()
form
.
find
(
".js-close-discussion-note-form"
).
remove
()
form
.
find
(
'.js-notify-commit-author'
).
remove
()
form
.
on
'ajax:success'
,
->
Wall
.
refresh
()
form
.
find
(
".js-note-text"
).
val
(
""
).
trigger
(
"input"
)
...
...
@@ -83,3 +67,17 @@
form
.
find
(
".js-attachment-filename"
).
text
(
filename
)
form
.
show
()
renderNote
:
(
note
)
->
author
=
'<strong class="wall-author">'
+
note
.
author
.
name
+
'</strong>'
body
=
'<span class="wall-text">'
+
note
.
body
+
'</span>'
file
=
''
time
=
'<abbr class="timeago" title="'
+
note
.
created_at
+
'">'
+
note
.
created_at
+
'</time>'
if
note
.
attachment
file
=
'<span class="wall-file"><a href="/files/note/'
+
note
.
id
+
'/'
+
note
.
attachment
+
'">'
+
note
.
attachment
+
'</a></span>'
html
=
'<li>'
+
author
+
body
+
file
+
time
+
'</li>'
$
(
'ul.notes'
).
append
(
html
)
app/assets/stylesheets/sections/wall.scss
View file @
b1bd3f12
.wall-page
{
.
new_note
{
.
wall-note-form
{
@extend
.span12
;
margin
:
0
;
...
...
@@ -23,7 +23,14 @@
}
.wall-file
{
margin-left
:
8px
;
background
:
#EEE
;
}
abbr
{
float
:
right
;
color
:
#AAA
;
border
:
none
;
}
}
}
app/views/events/event/_note.html.haml
View file @
b1bd3f12
...
...
@@ -11,7 +11,7 @@
#{
event
.
note_target_type
}
##{truncate event.note_target_id}
-
elsif
event
.
wall_note?
=
link_to
'wall'
,
wall_project
_path
(
event
.
project
)
=
link_to
'wall'
,
project_wall
_path
(
event
.
project
)
-
else
%strong
(deleted)
at
...
...
app/views/notify/note_wall_email.html.haml
View file @
b1bd3f12
%p
New message on
=
link_to
"Project Wall"
,
wall_project
_url
(
@note
.
project
,
anchor:
"note_
#{
@note
.
id
}
"
)
=
link_to
"Project Wall"
,
project_wall
_url
(
@note
.
project
,
anchor:
"note_
#{
@note
.
id
}
"
)
=
render
'note_message'
app/views/notify/note_wall_email.text.erb
View file @
b1bd3f12
New message on the project wall
<%=
@note
.
project
%>
<%=
url_for
(
wall_project
_url
(
@note
.
project
,
anchor:
"note_
#{
@note
.
id
}
"
))
%>
<%=
url_for
(
project_wall
_url
(
@note
.
project
,
anchor:
"note_
#{
@note
.
id
}
"
))
%>
<%=
@note
.
author_name
%>
...
...
app/views/walls/show.html.haml
View file @
b1bd3f12
...
...
@@ -2,9 +2,30 @@
%ul
.well-list.notes
.notes-busy.js-notes-busy
.js-main-target-form
-
if
can?
current_user
,
:write_note
,
@project
=
render
"notes/form"
.note-form-holder
=
form_for
[
@project
,
@note
],
remote:
true
,
html:
{
multipart:
true
,
id:
nil
,
class:
"new_note wall-note-form"
}
do
|
f
|
=
note_target_fields
.note_text_and_preview
=
f
.
text_area
:note
,
size:
255
,
class:
'note_text js-note-text js-gfm-input turn-on'
.note-form-actions
.buttons
=
f
.
submit
'Add Comment'
,
class:
"btn comment-btn grouped js-comment-button"
.note-form-option
=
label_tag
:notify
do
=
check_box_tag
:notify
,
1
,
false
%span
.light
Notify team via email
.note-form-option
%a
.choose-btn.btn.btn-small.js-choose-note-attachment-button
%i
.icon-paper-clip
%span
Choose File ...
%span
.file_name.js-attachment-filename
File name...
=
f
.
file_field
:attachment
,
class:
"js-note-attachment-input hide"
.clearfix
:javascript
$
(
function
(){
...
...
features/steps/shared/paths.rb
View file @
b1bd3f12
...
...
@@ -161,7 +161,7 @@ module SharedPaths
end
Given
"I visit my project's wall page"
do
visit
wall_project
_path
(
@project
)
visit
project_wall
_path
(
@project
)
end
Given
"I visit my project's wiki page"
do
...
...
spec/features/gitlab_flavored_markdown_spec.rb
View file @
b1bd3f12
...
...
@@ -198,7 +198,7 @@ describe "Gitlab Flavored Markdown" do
end
it
"should render in projects#wall"
,
js:
true
do
visit
wall_project
_path
(
project
)
visit
project_wall
_path
(
project
)
within
".new_note.js-main-target-form"
do
fill_in
"note_note"
,
with:
"see #
#{
issue
.
id
}
"
click_button
"Add Comment"
...
...
spec/features/notes_on_merge_requests_spec.rb
View file @
b1bd3f12
...
...
@@ -22,7 +22,7 @@ describe "On a merge request", js: true do
it
{
within
(
".js-main-target-form"
)
{
should_not
have_link
(
"Cancel"
)
}
}
# notifiactions
it
{
within
(
".js-main-target-form"
)
{
should
have_checked_field
(
"Notify team via email"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should
have_
un
checked_field
(
"Notify team via email"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should_not
have_checked_field
(
"Notify commit author"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should_not
have_unchecked_field
(
"Notify commit author"
)
}
}
...
...
@@ -127,7 +127,7 @@ describe "On a merge request diff", js: true, focus: true do
it
{
should
have_css
(
".js-close-discussion-note-form"
,
text:
"Cancel"
)
}
# notification options
it
{
should
have_checked_field
(
"Notify team via email"
)
}
it
{
should
have_
un
checked_field
(
"Notify team via email"
)
}
it
"shouldn't add a second form for same row"
do
find
(
"#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button"
).
trigger
(
"click"
)
...
...
spec/features/notes_on_wall_spec.rb
View file @
b1bd3f12
...
...
@@ -2,84 +2,40 @@ require 'spec_helper'
describe
"On the project wall"
,
js:
true
do
let!
(
:project
)
{
create
(
:project
)
}
let!
(
:commit
)
{
project
.
repository
.
commit
(
"bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
)
}
before
do
login_as
:user
project
.
team
<<
[
@user
,
:master
]
visit
wall_project
_path
(
project
)
visit
project_wall
_path
(
project
)
end
subject
{
page
}
describe
"the note form"
do
# main target form creation
it
{
should
have_css
(
".js-main-target-form"
,
visible:
true
,
count:
1
)
}
# button initalization
it
{
find
(
".js-main-target-form input[type=submit]"
).
value
.
should
==
"Add Comment"
}
it
{
within
(
".js-main-target-form"
)
{
should_not
have_link
(
"Cancel"
)
}
}
# notifiactions
it
{
within
(
".js-main-target-form"
)
{
should
have_checked_field
(
"Notify team via email"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should_not
have_checked_field
(
"Notify commit author"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should_not
have_unchecked_field
(
"Notify commit author"
)
}
}
describe
"without text"
do
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-preview-button"
,
visible:
false
)
}
}
end
it
{
should
have_css
(
".wall-note-form"
,
visible:
true
,
count:
1
)
}
it
{
find
(
".wall-note-form input[type=submit]"
).
value
.
should
==
"Add Comment"
}
it
{
within
(
".wall-note-form"
)
{
should
have_unchecked_field
(
"Notify team via email"
)
}
}
describe
"with text"
do
before
do
within
(
".
js-main-target
-form"
)
do
within
(
".
wall-note
-form"
)
do
fill_in
"note[note]"
,
with:
"This is awesome"
end
end
it
{
within
(
".js-main-target-form"
)
{
should_not
have_css
(
".js-comment-button[disabled]"
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-preview-button"
,
visible:
true
)
}
}
end
describe
"with preview"
do
before
do
within
(
".js-main-target-form"
)
do
fill_in
"note[note]"
,
with:
"This is awesome"
find
(
".js-note-preview-button"
).
trigger
(
"click"
)
end
end
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-preview"
,
text:
"This is awesome"
,
visible:
true
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-preview-button"
,
visible:
false
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-edit-button"
,
visible:
true
)
}
}
it
{
within
(
".wall-note-form"
)
{
should_not
have_css
(
".js-comment-button[disabled]"
)
}
}
end
end
describe
"when posting a note"
do
before
do
within
(
".
js-main-target
-form"
)
do
within
(
".
wall-note
-form"
)
do
fill_in
"note[note]"
,
with:
"This is awsome!"
find
(
".js-note-preview-button"
).
trigger
(
"click"
)
click_button
"Add Comment"
end
end
# note added
it
{
should
have_content
(
"This is awsome!"
)
}
# reset form
it
{
within
(
".js-main-target-form"
)
{
should
have_no_field
(
"note[note]"
,
with:
"This is awesome!"
)
}
}
# return from preview
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-preview"
,
visible:
false
)
}
}
it
{
within
(
".js-main-target-form"
)
{
should
have_css
(
".js-note-text"
,
visible:
true
)
}
}
it
"should be removable"
do
find
(
".js-note-delete"
).
trigger
(
"click"
)
should_not
have_css
(
".note"
)
end
it
{
within
(
".wall-note-form"
)
{
should
have_no_field
(
"note[note]"
,
with:
"This is awesome!"
)
}
}
end
end
spec/features/security/project_access_spec.rb
View file @
b1bd3f12
...
...
@@ -95,7 +95,7 @@ describe "Application access" do
end
describe
"GET /project_code/wall"
do
subject
{
wall_project
_path
(
project
)
}
subject
{
project_wall
_path
(
project
)
}
it
{
should
be_allowed_for
master
}
it
{
should
be_allowed_for
reporter
}
...
...
spec/mailers/notify_spec.rb
View file @
b1bd3f12
...
...
@@ -239,7 +239,7 @@ describe Notify do
end
describe
'on a project wall'
do
let
(
:note_on_the_wall_path
)
{
wall_project
_path
(
project
,
anchor:
"note_
#{
note
.
id
}
"
)
}
let
(
:note_on_the_wall_path
)
{
project_wall
_path
(
project
,
anchor:
"note_
#{
note
.
id
}
"
)
}
subject
{
Notify
.
note_wall_email
(
recipient
.
id
,
note
.
id
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment