sitediff 0.0.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/sitediff +9 -2
- data/lib/sitediff.rb +126 -81
- data/lib/sitediff/cache.rb +35 -6
- data/lib/sitediff/cli.rb +254 -119
- data/lib/sitediff/config.rb +362 -29
- data/lib/sitediff/config/creator.rb +53 -71
- data/lib/sitediff/config/preset.rb +75 -0
- data/lib/sitediff/crawler.rb +11 -15
- data/lib/sitediff/diff.rb +28 -9
- data/lib/sitediff/fetch.rb +9 -2
- data/lib/sitediff/files/diff.html.erb +20 -2
- data/lib/sitediff/files/jquery.min.js +2 -0
- data/lib/sitediff/files/normalize.css +349 -0
- data/lib/sitediff/files/report.html.erb +144 -0
- data/lib/sitediff/files/sidebyside.html.erb +5 -2
- data/lib/sitediff/files/sitediff.css +226 -30
- data/lib/sitediff/files/sitediff.js +176 -0
- data/lib/sitediff/report.rb +238 -0
- data/lib/sitediff/result.rb +47 -19
- data/lib/sitediff/sanitize.rb +29 -8
- data/lib/sitediff/sanitize/dom_transform.rb +45 -6
- data/lib/sitediff/sanitize/regexp.rb +23 -2
- data/lib/sitediff/uriwrapper.rb +56 -15
- data/lib/sitediff/webserver.rb +12 -3
- data/lib/sitediff/webserver/resultserver.rb +28 -33
- metadata +33 -16
- data/lib/sitediff/files/html_report.html.erb +0 -66
- data/lib/sitediff/files/rules/drupal.yaml +0 -63
- data/lib/sitediff/rules.rb +0 -65
@@ -0,0 +1,144 @@
|
|
1
|
+
<%
|
2
|
+
# Changed pages.
|
3
|
+
changed_pages = results.count { |result| !result.success? }
|
4
|
+
|
5
|
+
# Pages compared.
|
6
|
+
compared_pages = results.length
|
7
|
+
%>
|
8
|
+
<!DOCTYPE html>
|
9
|
+
<html>
|
10
|
+
<head>
|
11
|
+
<%# Important: without charset, chrome chokes on non-ascii characters %>
|
12
|
+
<title> SiteDiff Report</title>
|
13
|
+
<meta charset="utf-8" />
|
14
|
+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
15
|
+
<meta http-equiv="Pragma" content="no-cache" />
|
16
|
+
<meta http-equiv="Expires" content="0" />
|
17
|
+
<style>
|
18
|
+
<%= SiteDiff::Report.css %>
|
19
|
+
</style>
|
20
|
+
<script>
|
21
|
+
<%= SiteDiff::Report.js %>
|
22
|
+
</script>
|
23
|
+
</head>
|
24
|
+
<body class="page-overview" data-page="overview">
|
25
|
+
<div id="layout">
|
26
|
+
<div class="container">
|
27
|
+
<div class="statistical-info">
|
28
|
+
<div class="changed-pages">
|
29
|
+
<h3>Changed pages</h3>
|
30
|
+
<span class="count">
|
31
|
+
<%= changed_pages %>
|
32
|
+
</span>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="compared-pages">
|
36
|
+
<h3>Pages compared</h3>
|
37
|
+
<span class="count">
|
38
|
+
<%= compared_pages %>
|
39
|
+
</span>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="container">
|
45
|
+
<div class="site-info">
|
46
|
+
<% tags = %w[before after] %>
|
47
|
+
<% tags.each do |tag| %>
|
48
|
+
<div class="site site-<%= tag %>">
|
49
|
+
<% notes = ['base url']
|
50
|
+
notes << 'cached' if cache.read_tags.include?(tag.to_sym) %>
|
51
|
+
<h3 class="site__tag"><%= tag.capitalize %></h3>
|
52
|
+
<a href="<%= eval(tag) %>" class="site__url"><%= eval(tag) %></a>
|
53
|
+
<% if cache.read_tags.include?(tag.to_sym) %>
|
54
|
+
(<%= 'cached' if cache.read_tags.include?(tag.to_sym) %>)
|
55
|
+
<% end %>
|
56
|
+
</div>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<div class="sitediff-toolbar">
|
62
|
+
<div class="container">
|
63
|
+
<div class="toolbar__left">
|
64
|
+
<form class="filter-form">
|
65
|
+
|
66
|
+
<div class="form-item form-search form-item--search">
|
67
|
+
<label>Search</label>
|
68
|
+
<input type="search" id="input-search" autofocus placeholder="Search" />
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div class="form-item form-checkboxes form-item--status">
|
72
|
+
<div class="form-checkbox">
|
73
|
+
<input type="checkbox" id="input-status-changed" value="changed" />
|
74
|
+
<label for="input-status-changed">Changed</label>
|
75
|
+
</div>
|
76
|
+
<div class="form-checkbox">
|
77
|
+
<input type="checkbox" id="input-status-unchanged" value="unchanged" />
|
78
|
+
<label for="input-status-unchanged">Unchanged</label>
|
79
|
+
</div>
|
80
|
+
<div class="form-checkbox">
|
81
|
+
<input type="checkbox" id="input-status-error" value="error" />
|
82
|
+
<label for="input-status-error">Errors</label>
|
83
|
+
</div>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
</form>
|
87
|
+
</div>
|
88
|
+
</div>
|
89
|
+
</div>
|
90
|
+
|
91
|
+
<div class="container">
|
92
|
+
<table id="sitediff-report" cellspacing="0" cellpadding="0">
|
93
|
+
|
94
|
+
<colgroup>
|
95
|
+
<col class="path-col">
|
96
|
+
<col class="icon-col">
|
97
|
+
<col class="status-col">
|
98
|
+
</colgroup>
|
99
|
+
|
100
|
+
<thead>
|
101
|
+
<tr>
|
102
|
+
<th>Path</th>
|
103
|
+
<th> </th>
|
104
|
+
<th>Status</th>
|
105
|
+
</tr>
|
106
|
+
</thead>
|
107
|
+
|
108
|
+
<tbody>
|
109
|
+
<% results.each do |result| %>
|
110
|
+
<tr class="sitediff-result sitediff-result--<%= result.status_text %>" data-status="<%= result.status_text %>">
|
111
|
+
<td class="description">
|
112
|
+
<span class="path"><%= result.path %></span>
|
113
|
+
<div class="buttons">
|
114
|
+
<% unless relative %>
|
115
|
+
<a href="<%= result.url(:before, before, cache) %>" class="button-before" target="_blank">Before</a>
|
116
|
+
<a href="<%= result.url(:after, after, cache) %>" class="button-after" target="_blank">After</a>
|
117
|
+
<a href="/sidebyside<%= result.path %>" class="button-both">Both</a>
|
118
|
+
<% end %>
|
119
|
+
<% unless result.diff_url.nil? %>
|
120
|
+
<a href="<%= result.diff_url(relative) %>" class="button button-diff">View diff</a>
|
121
|
+
<% end %>
|
122
|
+
</div>
|
123
|
+
</td>
|
124
|
+
<td class="icon">
|
125
|
+
<span class="icon icon-result-<%= result.status_text %>"></span>
|
126
|
+
</td>
|
127
|
+
<td class="status">
|
128
|
+
<%= result.status_text.capitalize %>
|
129
|
+
</td>
|
130
|
+
</tr>
|
131
|
+
<% end %>
|
132
|
+
</tbody>
|
133
|
+
|
134
|
+
</table>
|
135
|
+
</div>
|
136
|
+
|
137
|
+
<footer id="footer">
|
138
|
+
<div class="credit">
|
139
|
+
Brought to you by <a href="https://evolvingweb.ca/?utm_source=sitediff&utm_medium=report&utm_content=footer-link" target="_blank">Evolving Web</a>.
|
140
|
+
</div>
|
141
|
+
</footer>
|
142
|
+
</div>
|
143
|
+
</body>
|
144
|
+
</html>
|
@@ -1,10 +1,13 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Comparison for <%= path %></title>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
6
|
+
<meta http-equiv="Pragma" content="no-cache" />
|
7
|
+
<meta http-equiv="Expires" content="0" />
|
4
8
|
<style>
|
5
|
-
<%= SiteDiff::
|
9
|
+
<%= SiteDiff::Report.css %>
|
6
10
|
</style>
|
7
|
-
<meta charset="utf-8" />
|
8
11
|
</head>
|
9
12
|
<body id="sidebyside">
|
10
13
|
<iframe src="<%= before %>"></iframe>
|
@@ -1,53 +1,249 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
* {
|
2
|
+
box-sizing: border-box;
|
3
|
+
outline: none;
|
4
4
|
}
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
|
6
|
+
a {
|
7
|
+
color: #6E73B7;
|
8
|
+
text-decoration: none;
|
9
|
+
}
|
10
|
+
|
11
|
+
body {
|
12
|
+
font-family: sans-serif;
|
13
|
+
font-size: 16px;
|
14
|
+
padding: 3em 0;
|
15
|
+
}
|
16
|
+
|
17
|
+
.container {
|
18
|
+
overflow: hidden;
|
19
|
+
margin: 0 auto;
|
20
|
+
padding-left: 1em;
|
21
|
+
padding-right: 1em;
|
22
|
+
max-width: 1280px;
|
23
|
+
}
|
24
|
+
|
25
|
+
#footer {
|
26
|
+
font-size: 90%;
|
27
|
+
margin-top: 2em;
|
8
28
|
text-align: center;
|
9
29
|
}
|
10
|
-
|
11
|
-
|
12
|
-
|
30
|
+
|
31
|
+
.site-info {
|
32
|
+
display: flex;
|
33
|
+
flex-direction: row;
|
34
|
+
align-items: center;
|
35
|
+
justify-content: space-between;
|
36
|
+
}
|
37
|
+
|
38
|
+
.site-info .site {
|
39
|
+
background-color: #F9F9FB;
|
40
|
+
flex-basis: 49%;
|
41
|
+
flex-grow: 0;
|
42
|
+
flex-shrink: 0;
|
43
|
+
padding: 1em;
|
44
|
+
}
|
45
|
+
|
46
|
+
.site__tag {
|
47
|
+
margin-top: 0;
|
48
|
+
margin-bottom: .5em;
|
49
|
+
}
|
50
|
+
|
51
|
+
/* Statistical info */
|
52
|
+
.statistical-info {
|
53
|
+
display: flex;
|
54
|
+
align-items: center;
|
55
|
+
justify-content: space-between;
|
56
|
+
flex-direction: row;
|
57
|
+
margin-bottom: 1em;
|
58
|
+
}
|
59
|
+
|
60
|
+
.statistical-info > div {
|
61
|
+
flex-basis: 49%;
|
62
|
+
}
|
63
|
+
|
64
|
+
.statistical-info h3 {
|
65
|
+
display: inline-block;
|
66
|
+
margin-right: 1em;
|
13
67
|
}
|
14
|
-
|
68
|
+
|
69
|
+
.statistical-info .count {
|
70
|
+
background-color: #eeeeee;
|
71
|
+
border-radius: 50%;
|
72
|
+
display: inline-block;
|
73
|
+
font-weight: bold;
|
74
|
+
line-height: 2em;
|
75
|
+
padding: .1em .25em 0;
|
76
|
+
height: 2em;
|
77
|
+
width: 2em;
|
15
78
|
text-align: center;
|
16
79
|
}
|
17
|
-
|
80
|
+
|
81
|
+
/* Buttons */
|
82
|
+
.button {
|
83
|
+
background-color: #EAECF3;
|
84
|
+
cursor: pointer;
|
85
|
+
display: inline-block;
|
86
|
+
font-size: .9em;
|
87
|
+
padding: .25em .5em .3em;
|
88
|
+
text-decoration: none;
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Forms.
|
93
|
+
*/
|
94
|
+
label[for] {
|
95
|
+
cursor: pointer;
|
96
|
+
}
|
97
|
+
|
98
|
+
/* Checkboxes */
|
99
|
+
.form-checkboxes .form-checkbox {
|
100
|
+
display: inline-block;
|
101
|
+
margin-right: .5em;
|
102
|
+
}
|
103
|
+
|
104
|
+
.form-checkbox input {
|
105
|
+
height: 1em;
|
106
|
+
width: 1em;
|
107
|
+
}
|
108
|
+
|
109
|
+
/* Search */
|
110
|
+
.form-search label {
|
111
|
+
display: none;
|
112
|
+
}
|
113
|
+
|
114
|
+
.form-search input {
|
115
|
+
font-size: .9em;
|
116
|
+
padding-left: .5em;
|
117
|
+
padding-right: .5em;
|
118
|
+
width: 200px;
|
119
|
+
}
|
120
|
+
|
121
|
+
/* SiteDiff Toolbar */
|
122
|
+
.sitediff-toolbar {
|
123
|
+
margin-top: 1em;
|
124
|
+
margin-bottom: 1em;
|
125
|
+
overflow: hidden;
|
126
|
+
padding-top: 5px;
|
127
|
+
padding-bottom: 5px;
|
128
|
+
}
|
129
|
+
|
130
|
+
.sitediff-toolbar .form-item {
|
131
|
+
display: inline-block;
|
132
|
+
margin-right: 1em;
|
133
|
+
}
|
134
|
+
|
135
|
+
.sitediff-toolbar .form-item:last-child {
|
136
|
+
margin-right: 0;
|
137
|
+
}
|
138
|
+
|
139
|
+
.sitediff-toolbar .toolbar__left {
|
140
|
+
float: left;
|
141
|
+
}
|
142
|
+
|
143
|
+
.sitediff-toolbar .toolbar__right {
|
144
|
+
float: right;
|
145
|
+
}
|
146
|
+
|
147
|
+
/* Table */
|
148
|
+
table {
|
149
|
+
width: 100%;
|
150
|
+
}
|
151
|
+
|
152
|
+
table thead {
|
153
|
+
background: #F9F9FB;
|
154
|
+
color: #999999;
|
155
|
+
}
|
156
|
+
|
157
|
+
td,
|
158
|
+
th {
|
18
159
|
text-align: left;
|
19
|
-
padding
|
160
|
+
padding: .4em .5em;
|
20
161
|
}
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
162
|
+
|
163
|
+
th {
|
164
|
+
border-bottom: 2px solid #EAECF3;
|
165
|
+
padding-top: .5em;
|
166
|
+
padding-bottom: .5em;
|
167
|
+
}
|
168
|
+
|
169
|
+
table tbody td {
|
170
|
+
border-bottom: 2px solid #F9F9FB;
|
171
|
+
}
|
172
|
+
|
173
|
+
table tbody tr:hover {
|
174
|
+
background-color: #F9F9FB;
|
175
|
+
}
|
176
|
+
|
177
|
+
table .path {
|
178
|
+
margin-right: 1em;
|
26
179
|
}
|
27
|
-
|
28
|
-
|
29
|
-
|
180
|
+
|
181
|
+
table td.description .buttons {
|
182
|
+
float: right;
|
183
|
+
}
|
184
|
+
|
185
|
+
table td.description a {
|
186
|
+
display: none;
|
187
|
+
margin-left: .4em;
|
188
|
+
}
|
189
|
+
|
190
|
+
table td.description:hover a {
|
191
|
+
display: inline-block;
|
30
192
|
}
|
31
|
-
|
32
|
-
|
33
|
-
|
193
|
+
|
194
|
+
table td.description .button-diff {
|
195
|
+
display: block;
|
34
196
|
}
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
.sitediff .diff-stat-col {
|
39
|
-
width: 10%;
|
197
|
+
|
198
|
+
table .icon-col {
|
199
|
+
width: 25px;
|
40
200
|
}
|
41
|
-
|
42
|
-
|
201
|
+
|
202
|
+
table .status-col {
|
203
|
+
width: 100px;
|
204
|
+
}
|
205
|
+
|
206
|
+
/* Icons */
|
207
|
+
.icon {
|
208
|
+
display: inline-block;
|
209
|
+
height: 1em;
|
210
|
+
width: 1em;
|
43
211
|
}
|
44
212
|
|
213
|
+
.icon-result-changed {
|
214
|
+
background-color: lightcoral;
|
215
|
+
border-radius: 50%;
|
216
|
+
}
|
217
|
+
|
218
|
+
.icon-result-unchanged {
|
219
|
+
background-color: lightgreen;
|
220
|
+
border-radius: 50%;
|
221
|
+
}
|
222
|
+
|
223
|
+
.icon-result-error {
|
224
|
+
background: khaki;
|
225
|
+
border-radius: 50%;
|
226
|
+
}
|
227
|
+
|
228
|
+
/* Side-by-side view */
|
45
229
|
#sidebyside {
|
46
230
|
margin: 0;
|
47
231
|
}
|
232
|
+
|
48
233
|
#sidebyside iframe {
|
49
234
|
float: left;
|
50
235
|
height: 100%;
|
51
236
|
width: 50%;
|
52
237
|
border: 0;
|
53
238
|
}
|
239
|
+
|
240
|
+
/* Page: Diff */
|
241
|
+
#diff-navigator {
|
242
|
+
background-color: #fefefe;
|
243
|
+
box-shadow: 0 0 .5em rgba(0, 0, 0, .25);
|
244
|
+
padding: .25em;
|
245
|
+
margin-top: 0;
|
246
|
+
position: fixed;
|
247
|
+
top: 0;
|
248
|
+
width: 100%;
|
249
|
+
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
/**
|
2
|
+
* @file
|
3
|
+
* SiteDiff report behaviors.
|
4
|
+
*/
|
5
|
+
|
6
|
+
/**
|
7
|
+
* SiteDiff namespace.
|
8
|
+
*/
|
9
|
+
var SiteDiff = SiteDiff || {};
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Scrolls the document to the said position.
|
13
|
+
*
|
14
|
+
* @param options
|
15
|
+
* Object specifying various options.
|
16
|
+
*
|
17
|
+
* x: X position.
|
18
|
+
* y: Y position.
|
19
|
+
* animate: Whether to animate.
|
20
|
+
* callback: A function to call after scrolling.
|
21
|
+
*/
|
22
|
+
SiteDiff.scrollToPosition = function (options) {
|
23
|
+
// Compute vertical and horizontal adjustments, if any.
|
24
|
+
// Example: Fixed elements, etc.
|
25
|
+
var xFix = 0;
|
26
|
+
var yFix = 0 - 100;
|
27
|
+
|
28
|
+
// Determine final x and y offsets.
|
29
|
+
var x = parseInt(options.x) + xFix;
|
30
|
+
x = Math.max(x, 0);
|
31
|
+
var y = parseInt(options.y) + yFix;
|
32
|
+
y = Math.max(y, 0);
|
33
|
+
|
34
|
+
// Perform the scroll with or without animation.
|
35
|
+
window.scrollTo(x, y);
|
36
|
+
|
37
|
+
// Trigger a callback, if any.
|
38
|
+
if (options.callback) {
|
39
|
+
options.callback();
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Scrolls to a DOM element on the page.
|
45
|
+
*
|
46
|
+
* @param el
|
47
|
+
* The DOM element.
|
48
|
+
*
|
49
|
+
* @param options
|
50
|
+
* Object specifying various options.
|
51
|
+
*
|
52
|
+
* "callback" to trigger after scrolling.
|
53
|
+
*/
|
54
|
+
SiteDiff.scrollToElement = function (el, options) {
|
55
|
+
options = options || {};
|
56
|
+
var callback = options.callback || function () {};
|
57
|
+
|
58
|
+
// See if the element exists.
|
59
|
+
var $el = $(el).first();
|
60
|
+
if ($el.length == 1) {
|
61
|
+
// Inject callback to focus on the element we scroll to.
|
62
|
+
options.x = 0;
|
63
|
+
options.y = $el.offset().top;
|
64
|
+
options.callback = function () {
|
65
|
+
$el.focus();
|
66
|
+
callback.call(el);
|
67
|
+
};
|
68
|
+
SiteDiff.scrollToPosition(options);
|
69
|
+
}
|
70
|
+
};
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Initialize behaviors.
|
74
|
+
*/
|
75
|
+
SiteDiff.init = function () {
|
76
|
+
// On the overview page.
|
77
|
+
switch ($(document.body).data('page')) {
|
78
|
+
case 'overview':
|
79
|
+
SiteDiff.initFilterForm();
|
80
|
+
break;
|
81
|
+
|
82
|
+
case 'diff':
|
83
|
+
SiteDiff.jumpToFirstDiff();
|
84
|
+
// TODO: Create a prev-next mechanism.
|
85
|
+
break;
|
86
|
+
}
|
87
|
+
};
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Initializes report filters.
|
91
|
+
*/
|
92
|
+
SiteDiff.initFilterForm = function () {
|
93
|
+
SiteDiff.initStatusFilter();
|
94
|
+
SiteDiff.initSearchFilter();
|
95
|
+
};
|
96
|
+
|
97
|
+
/**
|
98
|
+
* Initializes the "status" filter.
|
99
|
+
*/
|
100
|
+
SiteDiff.initStatusFilter = function () {
|
101
|
+
$('.form-item--status input')
|
102
|
+
.on('change', function () {
|
103
|
+
// Get a list of applied filters.
|
104
|
+
var appliedFilters = $('.form-item--status input:checked')
|
105
|
+
.map(function () {
|
106
|
+
return this.getAttribute('value');
|
107
|
+
// applied.push(this.getAttribute('value'));
|
108
|
+
// console.log(applied);
|
109
|
+
});
|
110
|
+
// Show only matching results, hide the rest.
|
111
|
+
$('#sitediff-report')
|
112
|
+
.find('.sitediff-result')
|
113
|
+
.each(function () {
|
114
|
+
var $row = $(this);
|
115
|
+
var status = $row.data('status');
|
116
|
+
if (
|
117
|
+
// Row matches applied filters.
|
118
|
+
$.inArray(status, appliedFilters) > -1 ||
|
119
|
+
// No filters are applied.
|
120
|
+
appliedFilters.length === 0
|
121
|
+
) {
|
122
|
+
$row.removeAttr('hidden');
|
123
|
+
}
|
124
|
+
else {
|
125
|
+
$row.attr('hidden', 'hidden');
|
126
|
+
}
|
127
|
+
});
|
128
|
+
});
|
129
|
+
};
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Initializes the "search" filter.
|
133
|
+
*/
|
134
|
+
SiteDiff.initSearchFilter = function () {
|
135
|
+
$('#input-search')
|
136
|
+
.on('change keyup', function () {
|
137
|
+
var keyword = $(this).val().toLowerCase();
|
138
|
+
|
139
|
+
// Filter the records.
|
140
|
+
// TODO: Trigger one event per 250ms.
|
141
|
+
$('#sitediff-report')
|
142
|
+
.find('.sitediff-result')
|
143
|
+
.each(function () {
|
144
|
+
var $row = $(this);
|
145
|
+
var path = $row.find('.path').text();
|
146
|
+
|
147
|
+
// If keyword matches, keep the row visible.
|
148
|
+
if (path.toLowerCase().indexOf(keyword) > -1) {
|
149
|
+
$row.attr('hidden', null);
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
$row.attr('hidden', 'hidden');
|
153
|
+
}
|
154
|
+
});
|
155
|
+
});
|
156
|
+
};
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Jumps to the first diff on the page.
|
160
|
+
*/
|
161
|
+
SiteDiff.jumpToFirstDiff = function () {
|
162
|
+
// Get the first diff hunk.
|
163
|
+
var $diff = $('#diff-container')
|
164
|
+
.find('.del, .ins')
|
165
|
+
.first();
|
166
|
+
if ($diff.length === 0) {
|
167
|
+
return;
|
168
|
+
}
|
169
|
+
|
170
|
+
// Scroll the window to it!
|
171
|
+
setTimeout(function () {
|
172
|
+
SiteDiff.scrollToElement($diff[0]);
|
173
|
+
}, 250);
|
174
|
+
};
|
175
|
+
|
176
|
+
$(document).ready(SiteDiff.init);
|