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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
35d0de8f
Commit
35d0de8f
authored
Mar 19, 2012
by
Steven Verbeek
Browse files
Options
Browse Files
Download
Plain Diff
merging upstream changes
parents
2a7cd2f1
cadf12c6
Changes
49
Show whitespace changes
Inline
Side-by-side
Showing
49 changed files
with
511 additions
and
168 deletions
+511
-168
app/assets/javascripts/application.js
app/assets/javascripts/application.js
+1
-0
app/assets/javascripts/merge_requests.js
app/assets/javascripts/merge_requests.js
+3
-3
app/assets/stylesheets/common.scss
app/assets/stylesheets/common.scss
+76
-5
app/assets/stylesheets/main.scss
app/assets/stylesheets/main.scss
+1
-1
app/assets/stylesheets/ui_basic.scss
app/assets/stylesheets/ui_basic.scss
+1
-1
app/controllers/dashboard_controller.rb
app/controllers/dashboard_controller.rb
+1
-1
app/controllers/merge_requests_controller.rb
app/controllers/merge_requests_controller.rb
+5
-7
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+1
-1
app/controllers/search_controller.rb
app/controllers/search_controller.rb
+12
-0
app/models/event.rb
app/models/event.rb
+1
-0
app/models/merge_request.rb
app/models/merge_request.rb
+89
-1
app/models/project.rb
app/models/project.rb
+22
-0
app/models/user.rb
app/models/user.rb
+4
-0
app/views/commits/show.html.haml
app/views/commits/show.html.haml
+2
-2
app/views/dashboard/_events_feed.html.haml
app/views/dashboard/_events_feed.html.haml
+0
-2
app/views/dashboard/_issues_feed.html.haml
app/views/dashboard/_issues_feed.html.haml
+3
-1
app/views/dashboard/_merge_requests_feed.html.haml
app/views/dashboard/_merge_requests_feed.html.haml
+4
-3
app/views/dashboard/_projects_feed.html.haml
app/views/dashboard/_projects_feed.html.haml
+4
-2
app/views/dashboard/index.html.haml
app/views/dashboard/index.html.haml
+2
-2
app/views/events/_event_changed_issue.html.haml
app/views/events/_event_changed_issue.html.haml
+6
-5
app/views/events/_event_changed_merge_request.html.haml
app/views/events/_event_changed_merge_request.html.haml
+6
-6
app/views/events/_event_new_issue.html.haml
app/views/events/_event_new_issue.html.haml
+2
-1
app/views/events/_event_new_merge_request.html.haml
app/views/events/_event_new_merge_request.html.haml
+2
-2
app/views/events/_event_push.html.haml
app/views/events/_event_push.html.haml
+8
-6
app/views/layouts/_app_menu.html.haml
app/views/layouts/_app_menu.html.haml
+7
-2
app/views/layouts/_head_panel.html.haml
app/views/layouts/_head_panel.html.haml
+3
-1
app/views/merge_requests/_commits.html.haml
app/views/merge_requests/_commits.html.haml
+3
-1
app/views/merge_requests/_how_to_merge.html.haml
app/views/merge_requests/_how_to_merge.html.haml
+1
-1
app/views/merge_requests/_merge_request.html.haml
app/views/merge_requests/_merge_request.html.haml
+1
-1
app/views/merge_requests/show.html.haml
app/views/merge_requests/show.html.haml
+23
-15
app/views/profile/password.html.haml
app/views/profile/password.html.haml
+43
-39
app/views/projects/_show.html.haml
app/views/projects/_show.html.haml
+1
-1
app/views/projects/empty.html.haml
app/views/projects/empty.html.haml
+1
-1
app/views/projects/index.html.haml
app/views/projects/index.html.haml
+9
-23
app/views/projects/show.html.haml
app/views/projects/show.html.haml
+6
-2
app/views/projects/show.js.haml
app/views/projects/show.js.haml
+0
-7
app/views/search/_result.html.haml
app/views/search/_result.html.haml
+1
-0
app/views/search/show.html.haml
app/views/search/show.html.haml
+41
-0
app/workers/post_receive.rb
app/workers/post_receive.rb
+6
-0
config/routes.rb
config/routes.rb
+2
-1
db/migrate/20120315111711_add_commits_diff_store_to_merge_request.rb
...20120315111711_add_commits_diff_store_to_merge_request.rb
+6
-0
db/migrate/20120315132931_add_merged_to_merge_request.rb
db/migrate/20120315132931_add_merged_to_merge_request.rb
+5
-0
db/schema.rb
db/schema.rb
+4
-1
doc/installation.md
doc/installation.md
+8
-3
resque.sh
resque.sh
+1
-1
spec/models/project_spec.rb
spec/models/project_spec.rb
+28
-0
spec/requests/dashboard_spec.rb
spec/requests/dashboard_spec.rb
+1
-15
spec/requests/merge_requests_spec.rb
spec/requests/merge_requests_spec.rb
+1
-1
vendor/assets/javascripts/jquery.highlight.js
vendor/assets/javascripts/jquery.highlight.js
+53
-0
No files found.
app/assets/javascripts/application.js
View file @
35d0de8f
...
...
@@ -11,6 +11,7 @@
//= require jquery.tagify
//= require jquery.cookie
//= require jquery.endless-scroll
//= require jquery.highlight
//= require bootstrap-modal
//= require modernizr
//= require chosen
...
...
app/assets/javascripts/merge_requests.js
View file @
35d0de8f
...
...
@@ -11,7 +11,7 @@ var MergeRequest = {
$
(
"
.tabs a.merge-notes-tab
"
).
live
(
"
click
"
,
function
(
e
)
{
$
(
"
.merge-request-diffs
"
).
hide
();
$
(
"
.merge
-request-
notes
"
).
show
();
$
(
"
.merge
_request_
notes
"
).
show
();
e
.
preventDefault
();
});
...
...
@@ -19,7 +19,7 @@ var MergeRequest = {
if
(
!
MergeRequest
.
diffs_loaded
)
{
MergeRequest
.
loadDiff
();
}
$
(
"
.merge
-request-
notes
"
).
hide
();
$
(
"
.merge
_request_
notes
"
).
hide
();
$
(
"
.merge-request-diffs
"
).
show
();
e
.
preventDefault
();
});
...
...
@@ -33,7 +33,7 @@ var MergeRequest = {
url
:
$
(
"
.merge-diffs-tab
"
).
attr
(
"
data-url
"
),
complete
:
function
(){
MergeRequest
.
diffs_loaded
=
true
;
$
(
"
.merge
-request-
notes
"
).
hide
();
$
(
"
.merge
_request_
notes
"
).
hide
();
$
(
"
.dashboard-loader
"
).
hide
()},
dataType
:
"
script
"
});
}
...
...
app/assets/stylesheets/common.scss
View file @
35d0de8f
...
...
@@ -3,7 +3,7 @@ a {
color
:
$link_color
;
&
:hover
{
text-decoration
:none
;
color
:
$
style_color
;
color
:
$
blue_link
;
}
&
.btn
{
...
...
@@ -11,6 +11,18 @@ a {
}
}
.btn
{
background-image
:
-webkit-gradient
(
linear
,
0
0
,
0
100%
,
from
(
#f1f1f1
)
,
color-stop
(
25%
,
#f1f1f1
)
,
to
(
#e6e6e6
));
background-image
:
-webkit-linear-gradient
(
#f1f1f1
,
#f1f1f1
25%
,
#e6e6e6
);
background-image
:
-moz-linear-gradient
(
top
,
#f1f1f1
,
#f1f1f1
25%
,
#e6e6e6
);
background-image
:
-ms-linear-gradient
(
#f1f1f1
,
#f1f1f1
25%
,
#e6e6e6
);
background-image
:
-o-linear-gradient
(
#f1f1f1
,
#f1f1f1
25%
,
#e6e6e6
);
background-image
:
linear-gradient
(
#f1f1f1
,
#f1f1f1
25%
,
#e6e6e6
);
&
:hover
{
}
}
a
:focus
{
outline
:
none
;
}
...
...
@@ -29,6 +41,29 @@ a:focus {
.label
{
background-color
:
#474D57
;
&
.pushed
{
background-color
:
$link_color
;
}
}
.pretty_label
{
@include
round-borders-all
(
4px
);
padding
:
2px
4px
;
background-image
:
-webkit-gradient
(
linear
,
0
0
,
0
26
,
color-stop
(
0
.076
,
#fefefe
)
,
to
(
#F6F7F8
));
background-image
:
-webkit-linear-gradient
(
#fefefe
7
.6%
,
#F6F7F8
);
background-image
:
-moz-linear-gradient
(
#fefefe
7
.6%
,
#F6F7F8
);
background-image
:
-o-linear-gradient
(
#fefefe
7
.6%
,
#F6F7F8
);
color
:
#777
;
border
:
1px
solid
#DEDFE1
;
&
.branch
{
border
:none
;
font-size
:
13px
;
background
:
#474D57
;
color
:
#fff
;
font-family
:
monospace
;
}
}
.tabs
>
li
>
a
,
.pills
>
li
>
a
{
...
...
@@ -807,12 +842,19 @@ p.time {
width
:
840px
;
margin
:auto
;
.wll
{
padding
:
5px
;
margin-top
:
5px
;
.dash_project_item
{
margin-bottom
:
10px
;
border
:none
;
&
:hover
{
background
:none
;
h4
{
color
:
#2FA0BB
;
.arrow
{
background
:
#2FA0BB
;
color
:
#fff
;
}
}
}
h4
{
...
...
@@ -887,7 +929,7 @@ p.time {
}
a
:last-child
h4
{
border
:none
;
}
a
.active
{
a
:hover
{
h4
{
color
:
#111
;
border-right
:
4px
solid
$styled_border_color
;
...
...
@@ -974,3 +1016,32 @@ p.time {
}
}
}
.highlight_word
{
background
:
#EEDC94
;
}
.status_info
{
font-size
:
14px
;
padding
:
5px
15px
;
line-height
:
24px
;
width
:
60px
;
text-align
:center
;
float
:left
;
margin-right
:
20px
;
}
.merge_request_status_holder
{
margin-bottom
:
20px
;
}
.arrow
{
float
:
right
;
background
:
#E3E5EA
;
padding
:
10px
;
border-radius
:
5px
;
text-shadow
:
none
;
color
:
#999
;
line-height
:
16px
;
font-weight
:bold
;
}
app/assets/stylesheets/main.scss
View file @
35d0de8f
...
...
@@ -15,7 +15,7 @@ $app_padding:20px;
$bg_color
:
#FFF
;
$styled_border_color
:
#2FA0BB
;
$color
:
"#4BB8D2"
;
$blue_link
:
"#2fa0bb"
;
$blue_link
:
#2fa0bb
;
/** Style colors **/
...
...
app/assets/stylesheets/ui_basic.scss
View file @
35d0de8f
...
...
@@ -17,7 +17,7 @@
color
:
$link_color
;
&
:hover
{
text-decoration
:none
;
color
:
$
style_color
;
color
:
$
blue_link
;
}
}
...
...
app/controllers/dashboard_controller.rb
View file @
35d0de8f
...
...
@@ -18,7 +18,7 @@ class DashboardController < ApplicationController
# Get authored or assigned open merge requests
def
merge_requests
@projects
=
current_user
.
projects
.
all
@merge_requests
=
MergeRequest
.
where
(
"author_id = :id or assignee_id = :id"
,
:id
=>
current_user
.
id
).
opened
.
order
(
"created_at DESC"
).
limit
(
40
)
@merge_requests
=
current_user
.
cared_merge_requests
.
order
(
"created_at DESC"
).
limit
(
40
)
end
# Get only assigned issues
...
...
app/controllers/merge_requests_controller.rb
View file @
35d0de8f
...
...
@@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController
@note
=
@project
.
notes
.
new
(
:noteable
=>
@merge_request
)
@commits
=
@project
.
repo
.
commits_between
(
@merge_request
.
target_branch
,
@merge_request
.
source_branch
).
map
{
|
c
|
Commit
.
new
(
c
)}.
sort_by
(
&
:created_at
).
reverse
render_full_content
# Get commits from repository
# or from cache if already merged
@commits
=
@merge_request
.
commits
respond_to
do
|
format
|
format
.
html
...
...
@@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController
respond_to
do
|
format
|
if
@merge_request
.
save
@merge_request
.
reload_code
format
.
html
{
redirect_to
[
@project
,
@merge_request
],
notice:
'Merge request was successfully created.'
}
format
.
json
{
render
json:
@merge_request
,
status: :created
,
location:
@merge_request
}
else
...
...
@@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController
def
update
respond_to
do
|
format
|
if
@merge_request
.
update_attributes
(
params
[
:merge_request
].
merge
(
:author_id_of_changes
=>
current_user
.
id
))
@merge_request
.
reload_code
format
.
html
{
redirect_to
[
@project
,
@merge_request
],
notice:
'Merge request was successfully updated.'
}
format
.
json
{
head
:ok
}
else
...
...
app/controllers/projects_controller.rb
View file @
35d0de8f
...
...
@@ -13,6 +13,7 @@ class ProjectsController < ApplicationController
def
index
@projects
=
current_user
.
projects
@projects
=
@projects
.
select
(
&
:last_activity_date
).
sort_by
(
&
:last_activity_date
).
reverse
@events
=
Event
.
where
(
:project_id
=>
@projects
.
map
(
&
:id
)).
recent
.
limit
(
40
)
end
def
new
...
...
@@ -78,7 +79,6 @@ class ProjectsController < ApplicationController
render
"projects/empty"
end
end
format
.
js
end
end
...
...
app/controllers/search_controller.rb
0 → 100644
View file @
35d0de8f
class
SearchController
<
ApplicationController
def
show
query
=
params
[
:search
]
if
query
.
blank?
@projects
=
[]
@merge_requests
=
[]
else
@projects
=
Project
.
search
(
query
).
limit
(
10
)
@merge_requests
=
MergeRequest
.
search
(
query
).
limit
(
10
)
end
end
end
app/models/event.rb
View file @
35d0de8f
...
...
@@ -7,6 +7,7 @@ class Event < ActiveRecord::Base
Reopened
=
4
Pushed
=
5
Commented
=
6
Merged
=
7
belongs_to
:project
belongs_to
:target
,
:polymorphic
=>
true
...
...
app/models/merge_request.rb
View file @
35d0de8f
require
File
.
join
(
Rails
.
root
,
"app/models/commit"
)
class
MergeRequest
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:author
,
:class_name
=>
"User"
belongs_to
:assignee
,
:class_name
=>
"User"
has_many
:notes
,
:as
=>
:noteable
,
:dependent
=>
:destroy
serialize
:st_commits
serialize
:st_diffs
attr_protected
:author
,
:author_id
,
:project
,
:project_id
attr_accessor
:author_id_of_changes
...
...
@@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base
scope
:closed
,
where
(
:closed
=>
true
)
scope
:assigned
,
lambda
{
|
u
|
where
(
:assignee_id
=>
u
.
id
)}
def
self
.
search
query
where
(
"title like :query"
,
:query
=>
"%
#{
query
}
%"
)
end
def
self
.
find_all_by_branch
(
branch_name
)
where
(
"source_branch like :branch or target_branch like :branch"
,
:branch
=>
branch_name
)
end
def
validate_branches
if
target_branch
==
source_branch
...
...
@@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base
end
end
def
reload_code
self
.
reloaded_commits
self
.
reloaded_diffs
end
def
new?
today?
&&
created_at
==
updated_at
end
def
diffs
st_diffs
||
[]
end
def
reloaded_diffs
if
open
?
&&
unmerged_diffs
.
any?
self
.
st_diffs
=
unmerged_diffs
save
end
diffs
end
def
unmerged_diffs
commits
=
project
.
repo
.
commits_between
(
target_branch
,
source_branch
).
map
{
|
c
|
Commit
.
new
(
c
)}
diffs
=
project
.
repo
.
diff
(
commits
.
first
.
prev_commit
.
id
,
commits
.
last
.
id
)
rescue
[]
end
def
last_commit
project
.
commit
(
source_branch
)
commits
.
first
end
def
merged?
merged
&&
merge_event
end
def
merge_event
self
.
project
.
events
.
where
(
:target_id
=>
self
.
id
,
:target_type
=>
"MergeRequest"
,
:action
=>
Event
::
Merged
).
last
end
def
closed_event
self
.
project
.
events
.
where
(
:target_id
=>
self
.
id
,
:target_type
=>
"MergeRequest"
,
:action
=>
Event
::
Closed
).
last
end
# Return the number of +1 comments (upvotes)
def
upvotes
notes
.
select
(
&
:
upvote?
).
size
end
def
commits
st_commits
||
[]
end
def
probably_merged?
unmerged_commits
.
empty?
&&
commits
.
any?
&&
open
?
end
def
open?
!
closed
end
def
mark_as_merged!
self
.
merged
=
true
self
.
closed
=
true
save
end
def
reloaded_commits
if
open
?
&&
unmerged_commits
.
any?
self
.
st_commits
=
unmerged_commits
save
end
commits
end
def
unmerged_commits
self
.
project
.
repo
.
commits_between
(
self
.
target_branch
,
self
.
source_branch
).
map
{
|
c
|
Commit
.
new
(
c
)}.
sort_by
(
&
:
created_at
).
reverse
end
def
merge!
(
user_id
)
self
.
mark_as_merged!
Event
.
create
(
:
project
=>
self
.
project
,
:action
=>
Event
::
Merged
,
:target_id
=>
self
.
id
,
:target_type
=>
"MergeRequest"
,
:author_id
=>
user_id
)
end
end
# == Schema Information
#
...
...
app/models/project.rb
View file @
35d0de8f
...
...
@@ -54,6 +54,10 @@ class Project < ActiveRecord::Base
UsersProject
.
access_roles
end
def
self
.
search
query
where
(
"name like :query or code like :query or path like :query"
,
:query
=>
"%
#{
query
}
%"
)
end
def
to_param
code
end
...
...
@@ -73,6 +77,24 @@ class Project < ActiveRecord::Base
)
end
def
update_merge_requests
(
oldrev
,
newrev
,
ref
,
author_key_id
)
return
true
unless
ref
=~
/heads/
branch_name
=
ref
.
gsub
(
"refs/heads/"
,
""
)
user
=
Key
.
find_by_identifier
(
author_key_id
).
user
c_ids
=
self
.
commits_between
(
oldrev
,
newrev
).
map
(
&
:id
)
# Update code for merge requests
mrs
=
self
.
merge_requests
.
opened
.
find_all_by_branch
(
branch_name
).
all
mrs
.
each
{
|
merge_request
|
merge_request
.
reload_code
}
# Close merge requests
mrs
=
self
.
merge_requests
.
opened
.
where
(
:target_branch
=>
branch_name
).
all
mrs
=
mrs
.
select
(
&
:last_commit
).
select
{
|
mr
|
c_ids
.
include?
(
mr
.
last_commit
.
id
)
}
mrs
.
each
{
|
merge_request
|
merge_request
.
merge!
(
user
.
id
)
}
true
end
def
execute_web_hooks
(
oldrev
,
newrev
,
ref
,
author_key_id
)
ref_parts
=
ref
.
split
(
'/'
)
...
...
app/models/user.rb
View file @
35d0de8f
...
...
@@ -86,6 +86,10 @@ class User < ActiveRecord::Base
)
end
end
def
cared_merge_requests
MergeRequest
.
where
(
"author_id = :id or assignee_id = :id"
,
:id
=>
self
.
id
).
opened
end
end
# == Schema Information
#
...
...
app/views/commits/show.html.haml
View file @
35d0de8f
...
...
@@ -12,8 +12,8 @@
=
@commit
.
committer_name
%small
=
@commit
.
committed_date
.
stamp
(
"Aug 21, 2011 9:23pm"
)
%
h
r
%pre
.commit_message
%
b
r
%pre
.commit_message
.prettyprint
=
commit_msg_with_link_to_issues
(
@project
,
@commit
.
safe_message
)
.clear
%br
...
...
app/views/dashboard/_events_feed.html.haml
deleted
100644 → 0
View file @
2a7cd2f1
=
render
@events
app/views/dashboard/_issues_feed.html.haml
View file @
35d0de8f
...
...
@@ -3,8 +3,10 @@
=
link_to
[
issue
.
project
,
issue
]
do
%p
%strong
%span
.label
=
issue
.
project
.
name
%span
.
pretty_
label
=
issue
.
project
.
name
–
Issue
#
=
issue
.
id
=
truncate
issue
.
title
,
:length
=>
50
%span
.right.cgray
=
issue
.
updated_at
.
stamp
(
"Aug 21, 2011"
)
app/views/dashboard/_merge_requests_feed.html.haml
View file @
35d0de8f
...
...
@@ -3,8 +3,9 @@
=
link_to
[
merge_request
.
project
,
merge_request
]
do
%p
%strong
%span
.label
=
merge_request
.
project
.
name
%span
.
pretty_
label
=
merge_request
.
project
.
name
–
Merge Request
#
=
merge_request
.
id
Merge Request ##{merge_request.id}
=
truncate
merge_request
.
title
,
:length
=>
50
%span
.right.cgray
=
merge_request
.
updated_at
.
stamp
(
"Aug 21, 2011"
)
app/views/dashboard/_projects_feed.html.haml
View file @
35d0de8f
-
@active_
projects
.
first
(
5
).
each
do
|
project
|
.wll
-
projects
.
first
(
5
).
each
do
|
project
|
%div
.dash_project_item
=
link_to
project
do
%h4
%span
.ico.project
...
...
@@ -7,3 +7,5 @@
%small
last activity at
=
project
.
last_activity_date
.
stamp
(
"Aug 25, 2011"
)
%span
.right.arrow
→
app/views/dashboard/index.html.haml
View file @
35d0de8f
...
...
@@ -20,7 +20,7 @@
.row
.dashboard_block
.row
.span10
=
render
"dashboard/projects_feed"
.span10
=
render
"dashboard/projects_feed"
,
:projects
=>
@active_projects
.span4.right
-
if
current_user
.
can_create_project?
.alert-message.block-message.warning
...
...
@@ -65,4 +65,4 @@
%hr
.row
.dashboard_block
=
render
"dashboard/events_feed"
.dashboard_block
=
render
@events
app/views/events/_event_changed_issue.html.haml
View file @
35d0de8f
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
-
if
event
.
closed?
%span
.label.important
-
if
event
.
closed?
closed
-
else
-
else
reopened
issue
issue
=
link_to
project_issue_path
(
event
.
project
,
event
.
issue
)
do
%strong
=
truncate
event
.
issue_title
at
...
...
app/views/events/_event_changed_merge_request.html.haml
View file @
35d0de8f
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
-
if
event
.
closed?
%span
.label.important
-
if
event
.
closed?
closed
-
else
-
else
reopened
merge request
merge request
=
link_to
project_merge_request_path
(
event
.
project
,
event
.
merge_request
)
do
%strong
=
truncate
event
.
merge_request_title
at
...
...
@@ -12,7 +13,6 @@ at
%span
.cgray
=
time_ago_in_words
(
event
.
created_at
)
ago.
%br
%span
.label
=
event
.
merge_request
.
source_branch
→
%span
.label
=
event
.
merge_request
.
target_branch
...
...
app/views/events/_event_new_issue.html.haml
View file @
35d0de8f
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
created new issue
%span
.label.success
created
new issue
=
link_to
project_issue_path
(
event
.
project
,
event
.
issue
)
do
%strong
=
truncate
event
.
issue_title
at
...
...
app/views/events/_event_new_merge_request.html.haml
View file @
35d0de8f
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
requested merge
%span
.label.success
requested
merge
=
link_to
project_merge_request_path
(
event
.
project
,
event
.
merge_request
)
do
%strong
=
truncate
event
.
merge_request_title
at
...
...
@@ -8,7 +9,6 @@ at
%span
.cgray
=
time_ago_in_words
(
event
.
created_at
)
ago.
%br
%span
.label
=
event
.
merge_request
.
source_branch
→
%span
.label
=
event
.
merge_request
.
target_branch
...
...
app/views/events/_event_push.html.haml
View file @
35d0de8f
-
if
event
.
new_branch?
||
event
.
new_tag?
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
pushed new
%span
.label.pushed
pushed
new
-
if
event
.
new_tag?
tag
=
link_to
project_commits_path
(
event
.
project
,
:ref
=>
event
.
tag_name
)
do
...
...
@@ -18,7 +19,8 @@
-
else
=
image_tag
gravatar_icon
(
event
.
author_email
),
:class
=>
"avatar"
%strong
#{
event
.
author_name
}
pushed to
%span
.label.pushed
pushed
to
=
link_to
project_commits_path
(
event
.
project
,
:ref
=>
event
.
branch_name
)
do
%strong
=
event
.
branch_name
at
...
...
@@ -30,10 +32,10 @@
=
link_to
compare_project_commits_path
(
event
.
project
,
:from
=>
event
.
commits
.
first
.
prev_commit_id
,
:to
=>
event
.
commits
.
last
.
id
)
do
Compare
#{
event
.
commits
.
first
.
commit
.
id
[
0
..
8
]
}
...
#{
event
.
commits
.
last
.
id
[
0
..
8
]
}
-
@project
=
event
.
project
%ul
.unstyled
-
if
event
.
commits
.
size
>
4
=
render
event
.
commits
[
0
..
2
]
%li
... and
#{
event
.
commits
.
size
-
3
}
more commits
%ul
.unstyled
.event_commits
-
if
event
.
commits
.
size
>
3
=
render
event
.
commits
[
0
..
.
2
]
%li
... and
#{
event
.
commits
.
size
-
2
}
more commits
-
else
=
render
event
.
commits
...
...
app/views/layouts/_app_menu.html.haml
View file @
35d0de8f
%nav
.main_menu
=
render
"layouts/const_menu_links"
=
link_to
"Projects"
,
projects_path
,
:class
=>
"
#{
"current"
if
current_page?
(
projects_path
)
}
"
=
link_to
"Issues"
,
dashboard_issues_path
,
:class
=>
"
#{
"current"
if
current_page?
(
dashboard_issues_path
)
}
"
,
:id
=>
"issues_slide"
=
link_to
"Requests"
,
dashboard_merge_requests_path
,
:class
=>
"
#{
"current"
if
current_page?
(
dashboard_merge_requests_path
)
}
"
,
:id
=>
"merge_requests_slide"
=
link_to
dashboard_issues_path
,
:class
=>
"
#{
"current"
if
current_page?
(
dashboard_issues_path
)
}
"
,
:id
=>
"issues_slide"
do
Issues
%span
.count
=
current_user
.
assigned_issues
.
opened
.
count
=
link_to
dashboard_merge_requests_path
,
:class
=>
"
#{
"current"
if
current_page?
(
dashboard_merge_requests_path
)
}
"
,
:id
=>
"merge_requests_slide"
do
Requests
%span
.count
=
current_user
.
cared_merge_requests
.
count
=
link_to
"Search"
,
search_path
,
:class
=>
"
#{
"current"
if
current_page?
(
search_path
)
}
"
=
link_to
"Help"
,
help_path
,
:class
=>
"
#{
"current"
if
controller
.
controller_name
==
"help"
}
"
app/views/layouts/_head_panel.html.haml
View file @
35d0de8f
...
...
@@ -7,7 +7,9 @@
%h1
GITLAB
%h1
.project_name
=
title
.search
=
text_field_tag
"search"
,
nil
,
:placeholder
=>
"Search"
,
:class
=>
"search-input"
.search
=
form_tag
search_path
,
:method
=>
:get
do
|
f
|
=
text_field_tag
"search"
,
nil
,
:placeholder
=>
"Search"
,
:class
=>
"search-input"
-
if
current_user
.
is_admin?
=
link_to
admin_projects_path
,
:class
=>
"admin_link"
,
:title
=>
"Admin area"
do
=
image_tag
"admin.PNG"
,
:width
=>
16
...
...
app/views/merge_requests/_commits.html.haml
View file @
35d0de8f
...
...
@@ -2,7 +2,9 @@
.ui-box
%h5
Commits
.merge-request-commits
%ul
.unstyled
=
render
@commits
%ul
.unstyled
-
@commits
.
each
do
|
commit
|
=
render
"commits/commit"
,
:commit
=>
commit
-
else
%h5
...
...
app/views/merge_requests/_how_to_merge.html.haml
View file @
35d0de8f
...
...
@@ -15,7 +15,7 @@
:javascript
$
(
function
(){
var
modal
=
$
(
'
#modal_merge_info
'
).
modal
({
modal
:
true
});
$
(
'
.
info
_link
'
).
bind
(
"
click
"
,
function
(){
$
(
'
.
how_to_merge
_link
'
).
bind
(
"
click
"
,
function
(){
modal
.
show
();
});
$
(
'
.modal-header .close
'
).
bind
(
"
click
"
,
function
(){
...
...
app/views/merge_requests/_merge_request.html.haml
View file @
35d0de8f
...
...
@@ -6,7 +6,7 @@
=
time_ago_in_words
(
merge_request
.
created_at
)
ago
-
if
merge_request
.
notes
.
any?
%span
.label
=
pluralize
merge_request
.
notes
.
count
,
'note'
%span
.
pretty_
label
=
pluralize
merge_request
.
notes
.
count
,
'note'
-
if
merge_request
.
upvotes
>
0
%span
.label.success
=
"+
#{
merge_request
.
upvotes
}
"
.right
...
...
app/views/merge_requests/show.html.haml
View file @
35d0de8f
%h3
=
"Merge Request #
#{
@merge_request
.
id
}
:"
%span
.
label
=
@merge_request
.
source_branch
%span
.
pretty_label.branch
=
@merge_request
.
source_branch
→
%span
.
label
=
@merge_request
.
target_branch
%span
.
pretty_label.branch
=
@merge_request
.
target_branch
%small
created at
...
...
@@ -11,9 +11,7 @@
%span
.right
-
if
can?
(
current_user
,
:modify_merge_request
,
@merge_request
)
-
if
@merge_request
.
closed
=
link_to
'Reopen'
,
project_merge_request_path
(
@project
,
@merge_request
,
:merge_request
=>
{
:closed
=>
false
},
:status_only
=>
true
),
:method
=>
:put
,
:class
=>
"btn"
-
else
-
if
@merge_request
.
open?
=
link_to
'Close'
,
project_merge_request_path
(
@project
,
@merge_request
,
:merge_request
=>
{
:closed
=>
true
},
:status_only
=>
true
),
:method
=>
:put
,
:class
=>
"btn"
,
:title
=>
"Close merge request"
=
link_to
edit_project_merge_request_path
(
@project
,
@merge_request
),
:class
=>
"btn"
do
Edit
...
...
@@ -28,17 +26,27 @@
%hr
-
if
@merge_request
.
closed
.alert-message.error
Closed
-
else
.alert-message.success
=
link_to
"#"
,
:class
=>
"info_link"
,
:title
=>
"How To Merge"
do
=
image_tag
"Info-UI.PNG"
Open
.merge_request_status_holder
-
if
@merge_request
.
closed
%h5
.alert-message.error.status_info
Closed
-
if
@merge_request
.
merged?
%span
Merged by
#{
@merge_request
.
merge_event
.
author_name
}
%small
#{
time_ago_in_words
(
@merge_request
.
merge_event
.
created_at
)
}
ago.
-
elsif
@merge_request
.
closed_event
%span
Closed by
#{
@merge_request
.
closed_event
.
author_name
}
%small
#{
time_ago_in_words
(
@merge_request
.
closed_event
.
created_at
)
}
ago.
%br
-
else
%h5
.alert-message.success.status_info
Open
=
link_to
"How to merge"
,
"#"
,
:class
=>
"vlink how_to_merge_link"
,
:title
=>
"How To Merge"
=
render
"merge_requests/how_to_merge"
%div
.well
%div
.well
.prettyprint
%div
%cite
.cgray
Created by
=
image_tag
gravatar_icon
(
@merge_request
.
author_email
),
:width
=>
16
,
:class
=>
"lil_av"
...
...
app/views/profile/password.html.haml
View file @
35d0de8f
%h3
Password
%hr
=
form_for
@user
,
:url
=>
profile_password_path
,
:method
=>
:put
do
|
f
|
.row
.span8
%h3
Password
%hr
=
form_for
@user
,
:url
=>
profile_password_path
,
:method
=>
:put
do
|
f
|
.data
.alert-message.block-message.warning
%p
After successfull password update you will be redirected to login page where you should login with new password
...
...
@@ -19,16 +21,18 @@
.actions
=
f
.
submit
'Save'
,
:class
=>
"btn"
%h3
.span7.right
%h3
Private token
%span
.cred.right
keep it in secret!
%hr
=
form_for
@user
,
:url
=>
profile_reset_private_token_path
,
:method
=>
:put
do
|
f
|
%hr
=
form_for
@user
,
:url
=>
profile_reset_private_token_path
,
:method
=>
:put
do
|
f
|
.data
.alert-message.block-message.warning
%p
Private token used to access application resources without authentication.
%p
For example its required to access commits feed.
%hr
%p
* required for rss feed
%p
.cgray
-
if
current_user
.
private_token
=
text_field_tag
"token"
,
current_user
.
private_token
...
...
app/views/projects/_show.html.haml
View file @
35d0de8f
%h
4
.title
%h
5
.title
=
@project
.
name
%br
%div
...
...
app/views/projects/empty.html.haml
View file @
35d0de8f
...
...
@@ -6,7 +6,7 @@
%li
Visit profile
→
keys and add public key of every machine you want to use for work with gitlabhq.
.alert-message.block-message.error
%ul
.alert_holder
%ul
.
unstyled.
alert_holder
%li
You should push repository to proceed.
%li
After push you will be able to browse code, commits etc.
...
...
app/views/projects/index.html.haml
View file @
35d0de8f
-
if
@projects
.
any?
.row
.span4
.span11
=
render
@events
.span5.right
%div
.leftbar.ui-box
%h5
Projects
%small
(
#{
@projects
.
count
}
)
-
if
current_user
.
can_create_project?
%span
.right
=
link_to
new_project_path
,
:class
=>
"btn very_small info"
do
New Project
.content_list
-
@projects
.
each
do
|
project
|
=
link_to
project_path
(
project
),
:
remote
=>
true
,
:
class
=>
dom_class
(
project
)
do
=
link_to
project_path
(
project
),
:class
=>
dom_class
(
project
)
do
%h4
%span
.ico.project
=
truncate
(
project
.
name
,
:length
=>
22
)
.span12.right
.show_holder.ui-box.padded
.loading
=
truncate
(
project
.
name
,
:length
=>
25
)
%span
.right
→
-
else
%h3
Nothing here
...
...
@@ -31,20 +34,3 @@
New Project »
-
else
If you will be added to project - it will be displayed here
:javascript
$
(
function
(){
$
(
"
a.project
"
).
live
(
"
ajax:before
"
,
function
()
{
$
(
"
.show_holder
"
).
html
(
"
<div class='loading'>
"
);
$
(
'
a.project
'
).
removeClass
(
"
active
"
);
$
(
this
).
addClass
(
"
active
"
);
});
$
(
'
a.project:first-child
'
).
trigger
(
"
click
"
);
});
-
if
@projects
.
count
==
@limit
:javascript
$
(
function
(){
Pager
.
init
(
#{
@limit
}
);
});
app/views/projects/show.html.haml
View file @
35d0de8f
...
...
@@ -21,9 +21,13 @@
=
text_field_tag
:project_clone
,
@project
.
url_to_repo
,
:class
=>
"xlarge one_click_select git_clone_url"
-
if
@project
.
description
.
present?
=
markdown
@project
.
description
.prettyprint
=
markdown
@project
.
description
-
unless
@events
.
blank?
%h5
.cgray
Recent Activity
%br
%h5
.cgray
%span
.ico.activities
Recent Activity
%hr
.content_list
=
render
@events
app/views/projects/show.js.haml
deleted
100644 → 0
View file @
2a7cd2f1
-
if
@project
.
repo_exists?
&&
@project
.
has_commits?
:plain
$(".show_holder").html("
#{
escape_javascript
(
render
(
:partial
=>
'projects/show'
))
}
");
-
else
:plain
$(".show_holder").html("
#{
escape_javascript
(
render
(
:template
=>
'projects/empty'
))
}
");
app/views/search/_result.html.haml
0 → 100644
View file @
35d0de8f
app/views/search/show.html.haml
0 → 100644
View file @
35d0de8f
=
form_tag
search_path
,
:method
=>
:get
do
|
f
|
.padded
=
label_tag
:search
,
"Looking for"
.input
=
text_field_tag
:search
,
params
[
:search
],
:placeholder
=>
"issue 143"
,
:class
=>
"xxlarge"
=
submit_tag
'Search'
,
:class
=>
"btn primary"
-
if
params
[
:search
].
present?
%br
%h3
Search results
%hr
.search_results
-
if
@projects
.
empty?
&&
@merge_requests
.
empty?
%h3
%small
Nothing here
-
else
-
if
@projects
.
any?
-
@projects
.
each
do
|
project
|
=
link_to
project
do
%h4
%span
.ico.project
=
project
.
name
%small
last activity at
=
project
.
last_activity_date
.
stamp
(
"Aug 25, 2011"
)
-
if
@merge_requests
.
any?
-
@merge_requests
.
each
do
|
merge_request
|
=
link_to
[
merge_request
.
project
,
merge_request
]
do
%h5
Merge Request
#
=
merge_request
.
id
–
=
truncate
merge_request
.
title
,
:length
=>
50
%small
updated at
=
merge_request
.
updated_at
.
stamp
(
"Aug 25, 2011"
)
%strong
%span
.label
=
merge_request
.
project
.
name
:javascript
$
(
function
()
{
$
(
"
.search_results
"
).
highlight
(
"
#{
params
[
:search
]
}
"
);
})
app/workers/post_receive.rb
View file @
35d0de8f
...
...
@@ -8,7 +8,13 @@ class PostReceive
# Ignore push from non-gitlab users
return
false
unless
Key
.
find_by_identifier
(
author_key_id
)
# Create push event
project
.
observe_push
(
oldrev
,
newrev
,
ref
,
author_key_id
)
# Close merged MR
project
.
update_merge_requests
(
oldrev
,
newrev
,
ref
,
author_key_id
)
# Execute web hooks
project
.
execute_web_hooks
(
oldrev
,
newrev
,
ref
,
author_key_id
)
end
end
config/routes.rb
View file @
35d0de8f
Gitlab
::
Application
.
routes
.
draw
do
get
'search'
=>
"search#show"
# Optionally, enable Resque here
require
'resque/server'
...
...
@@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do
get
"dashboard"
,
:to
=>
"dashboard#index"
get
"dashboard/issues"
,
:to
=>
"dashboard#issues"
get
"dashboard/merge_requests"
,
:to
=>
"dashboard#merge_requests"
get
"dashboard/activities"
,
:to
=>
"dashboard#activities"
#get "profile/:id", :to => "profile#show"
...
...
db/migrate/20120315111711_add_commits_diff_store_to_merge_request.rb
0 → 100644
View file @
35d0de8f
class
AddCommitsDiffStoreToMergeRequest
<
ActiveRecord
::
Migration
def
change
add_column
:merge_requests
,
:st_commits
,
:text
,
:null
=>
true
add_column
:merge_requests
,
:st_diffs
,
:text
,
:null
=>
true
end
end
db/migrate/20120315132931_add_merged_to_merge_request.rb
0 → 100644
View file @
35d0de8f
class
AddMergedToMergeRequest
<
ActiveRecord
::
Migration
def
change
add_column
:merge_requests
,
:merged
,
:boolean
,
:null
=>
false
,
:default
=>
false
end
end
db/schema.rb
View file @
35d0de8f
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
:version
=>
201203
07095918
)
do
ActiveRecord
::
Schema
.
define
(
:version
=>
201203
15132931
)
do
create_table
"events"
,
:force
=>
true
do
|
t
|
t
.
string
"target_type"
...
...
@@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do
t
.
boolean
"closed"
,
:default
=>
false
,
:null
=>
false
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
text
"st_commits"
t
.
text
"st_diffs"
t
.
boolean
"merged"
,
:default
=>
false
,
:null
=>
false
end
add_index
"merge_requests"
,
[
"project_id"
],
:name
=>
"index_merge_requests_on_project_id"
...
...
doc/installation.md
View file @
35d0de8f
...
...
@@ -209,7 +209,7 @@ Application can be started with next command:
cd /home/gitlab/gitlab
sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb
sudo -u gitlab unicorn_rails -c config/unicorn.rb -E production -D
sudo -u gitlab
bundle exec
unicorn_rails -c config/unicorn.rb -E production -D
Edit /etc/nginx/nginx.conf. Add next code to
**http**
section:
...
...
@@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab:
NAME=unicorn
DESC="Gitlab service"
PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
case "$1" in
start)
CD_TO_APP_DIR="cd /home/gitlab/gitlab"
START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS"
START_RESQUE_PROCESS="./resque.sh"
echo -n "Starting $DESC: "
if [ `whoami` = root ]; then
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS"
sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
&& $START_RESQUE_PROCESS
"
else
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
&& $START_RESQUE_PROCESS
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
kill -QUIT `cat $PID`
kill -QUIT `cat $RESQUE_PID`
echo "$NAME."
;;
restart)
echo -n "Restarting $DESC: "
kill -USR2 `cat $PID`
kill -USR2 `cat $RESQUE_PID`
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID`
kill -HUP `cat $RESQUE_PID`
echo "$NAME."
;;
*)
...
...
resque.sh
View file @
35d0de8f
mkdir
tmp/pids
nohup
bundle
exec
rake environment resque:work
QUEUE
=
*
RAILS_ENV
=
production
PIDFILE
=
tmp/pids/resque_worker
_QUEUE.pid &
>>
log/resque_worker_QUEUE
.log 2>&1
nohup
bundle
exec
rake environment resque:work
QUEUE
=
*
RAILS_ENV
=
production
PIDFILE
=
tmp/pids/resque_worker
.pid &
>>
log/resque_worker
.log 2>&1
spec/models/project_spec.rb
View file @
35d0de8f
...
...
@@ -160,6 +160,34 @@ describe Project do
end
end
end
describe
:update_merge_requests
do
let
(
:project
)
{
Factory
:project
}
before
do
@merge_request
=
Factory
:merge_request
,
:project
=>
project
,
:merged
=>
false
,
:closed
=>
false
@key
=
Factory
:key
,
:user_id
=>
project
.
owner
.
id
end
it
"should close merge request if last commit from source branch was pushed to target branch"
do
@merge_request
.
reloaded_commits
@merge_request
.
last_commit
.
id
.
should
==
"bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
project
.
update_merge_requests
(
"8716fc78f3c65bbf7bcf7b574febd583bc5d2812"
,
"bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
,
"refs/heads/stable"
,
@key
.
identifier
)
@merge_request
.
reload
@merge_request
.
merged
.
should
be_true
@merge_request
.
closed
.
should
be_true
end
it
"should update merge request commits with new one if pushed to source branch"
do
@merge_request
.
last_commit
.
should
==
nil
project
.
update_merge_requests
(
"8716fc78f3c65bbf7bcf7b574febd583bc5d2812"
,
"bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
,
"refs/heads/master"
,
@key
.
identifier
)
@merge_request
.
reload
@merge_request
.
last_commit
.
id
.
should
==
"bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
end
end
end
# == Schema Information
#
...
...
spec/requests/dashboard_spec.rb
View file @
35d0de8f
require
'spec_helper'
__END__
# Disabled for now
describe
"Dashboard"
do
before
do
@project
=
Factory
:project
...
...
@@ -22,19 +20,7 @@ describe "Dashboard" do
end
it
"should have projects panel"
do
within ".project-list" do
page
.
should
have_content
(
@project
.
name
)
end
end
# Temporary disabled cause of travis
# TODO: fix or rewrite
#it "should have news feed" do
#within "#news-feed" do
#page.should have_content("commit")
#page.should have_content(@project.commit.author.name)
#page.should have_content(@project.commit.safe_message)
#end
#end
end
end
spec/requests/merge_requests_spec.rb
View file @
35d0de8f
...
...
@@ -42,7 +42,7 @@ describe "MergeRequests" do
it
{
should
have_content
(
@merge_request
.
title
[
0
..
10
])
}
it
"Show page should inform user that merge request closed"
do
page
.
should
have_content
"
Reopen
"
page
.
should
have_content
"
Closed
"
end
end
end
...
...
vendor/assets/javascripts/jquery.highlight.js
0 → 100644
View file @
35d0de8f
/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery
.
fn
.
highlight
=
function
(
pat
)
{
function
innerHighlight
(
node
,
pat
)
{
var
skip
=
0
;
if
(
node
.
nodeType
==
3
)
{
var
pos
=
node
.
data
.
toUpperCase
().
indexOf
(
pat
);
if
(
pos
>=
0
)
{
var
spannode
=
document
.
createElement
(
'
span
'
);
spannode
.
className
=
'
highlight_word
'
;
var
middlebit
=
node
.
splitText
(
pos
);
var
endbit
=
middlebit
.
splitText
(
pat
.
length
);
var
middleclone
=
middlebit
.
cloneNode
(
true
);
spannode
.
appendChild
(
middleclone
);
middlebit
.
parentNode
.
replaceChild
(
spannode
,
middlebit
);
skip
=
1
;
}
}
else
if
(
node
.
nodeType
==
1
&&
node
.
childNodes
&&
!
/
(
script|style
)
/i
.
test
(
node
.
tagName
))
{
for
(
var
i
=
0
;
i
<
node
.
childNodes
.
length
;
++
i
)
{
i
+=
innerHighlight
(
node
.
childNodes
[
i
],
pat
);
}
}
return
skip
;
}
return
this
.
each
(
function
()
{
innerHighlight
(
this
,
pat
.
toUpperCase
());
});
};
jQuery
.
fn
.
removeHighlight
=
function
()
{
return
this
.
find
(
"
span.highlight
"
).
each
(
function
()
{
this
.
parentNode
.
firstChild
.
nodeName
;
with
(
this
.
parentNode
)
{
replaceChild
(
this
.
firstChild
,
this
);
normalize
();
}
}).
end
();
};
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