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
5de8971d
Commit
5de8971d
authored
Jan 15, 2016
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Whoops, forgot to add files
parent
13f10efc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
160 additions
and
0 deletions
+160
-0
lib/gitlab/diff/inline_diff.rb
lib/gitlab/diff/inline_diff.rb
+75
-0
lib/gitlab/diff/inline_diff_marker.rb
lib/gitlab/diff/inline_diff_marker.rb
+85
-0
No files found.
lib/gitlab/diff/inline_diff.rb
0 → 100644
View file @
5de8971d
module
Gitlab
module
Diff
class
InlineDiff
attr_accessor
:lines
def
initialize
(
lines
)
@lines
=
lines
end
def
inline_diffs
inline_diffs
=
[]
local_edit_indexes
.
each
do
|
index
|
old_index
=
index
new_index
=
index
+
1
old_line
=
@lines
[
old_index
]
new_line
=
@lines
[
new_index
]
suffixless_old_line
=
old_line
[
1
..-
1
]
suffixless_new_line
=
new_line
[
1
..-
1
]
# Skip inline diff if empty line was replaced with content
next
if
suffixless_old_line
==
""
# Add one, because this is based on the suffixless version
lcp
=
longest_common_prefix
(
suffixless_old_line
,
suffixless_new_line
)
+
1
lcs
=
longest_common_suffix
(
suffixless_old_line
,
suffixless_new_line
)
old_diff_range
=
lcp
..
(
old_line
.
length
-
lcs
-
1
)
new_diff_range
=
lcp
..
(
new_line
.
length
-
lcs
-
1
)
inline_diffs
[
old_index
]
=
[
old_diff_range
]
if
old_diff_range
.
begin
<=
old_diff_range
.
end
inline_diffs
[
new_index
]
=
[
new_diff_range
]
if
new_diff_range
.
begin
<=
new_diff_range
.
end
end
inline_diffs
end
private
def
local_edit_indexes
line_prefixes
=
@lines
.
map
{
|
line
|
line
.
match
(
/\A([+-])/
)
?
$1
:
' '
}
joined_line_prefixes
=
"
#{
line_prefixes
.
join
}
"
offset
=
0
local_edit_indexes
=
[]
while
index
=
joined_line_prefixes
.
index
(
" -+ "
,
offset
)
local_edit_indexes
<<
index
offset
=
index
+
1
end
local_edit_indexes
end
def
longest_common_prefix
(
a
,
b
)
max_length
=
[
a
.
length
,
b
.
length
].
max
length
=
0
(
0
..
max_length
-
1
).
each
do
|
pos
|
old_char
=
a
[
pos
]
new_char
=
b
[
pos
]
break
if
old_char
!=
new_char
length
+=
1
end
length
end
def
longest_common_suffix
(
a
,
b
)
longest_common_prefix
(
a
.
reverse
,
b
.
reverse
)
end
end
end
end
lib/gitlab/diff/inline_diff_marker.rb
0 → 100644
View file @
5de8971d
module
Gitlab
module
Diff
class
InlineDiffMarker
attr_accessor
:raw_line
,
:rich_line
def
initialize
(
raw_line
,
rich_line
=
raw_line
)
@raw_line
=
raw_line
@rich_line
=
rich_line
end
def
mark
(
line_inline_diffs
)
offset
=
0
line_inline_diffs
.
each
do
|
inline_diff_range
|
inline_diff_positions
=
position_mapping
[
inline_diff_range
]
marker_ranges
=
collapse_ranges
(
inline_diff_positions
)
marker_ranges
.
each
do
|
range
|
offset
=
insert_around_range
(
rich_line
,
range
,
"<span class='idiff'>"
,
"</span>"
,
offset
)
end
end
rich_line
end
def
position_mapping
@position_mapping
||=
begin
mapping
=
[]
raw_pos
=
0
rich_pos
=
0
(
0
..
raw_line
.
length
).
each
do
|
raw_pos
|
raw_char
=
raw_line
[
raw_pos
]
rich_char
=
rich_line
[
rich_pos
]
while
rich_char
==
'<'
until
rich_char
==
'>'
rich_pos
+=
1
rich_char
=
rich_line
[
rich_pos
]
end
rich_pos
+=
1
rich_char
=
rich_line
[
rich_pos
]
end
mapping
[
raw_pos
]
=
rich_pos
rich_pos
+=
1
end
mapping
end
end
def
collapse_ranges
(
positions
)
return
[]
if
positions
.
empty?
ranges
=
[]
start
=
prev
=
positions
[
0
]
range
=
start
..
prev
positions
[
1
..-
1
].
each
do
|
pos
|
if
pos
==
prev
+
1
range
=
start
..
pos
prev
=
pos
else
ranges
<<
range
start
=
prev
=
pos
range
=
start
..
prev
end
end
ranges
<<
range
ranges
end
def
insert_around_range
(
text
,
range
,
before
,
after
,
offset
=
0
)
text
.
insert
(
offset
+
range
.
begin
,
before
)
offset
+=
before
.
length
text
.
insert
(
offset
+
range
.
end
+
1
,
after
)
offset
+=
after
.
length
offset
end
end
end
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