Commit c42ada9bee6e95b6fd3ebdc55d4b269f7e18d9f6

Authored by Riyad Preukschas
1 parent 45dcb1b5

Allow linking to file lines

Supported formats: "L12" for single lines and "L12-34" for multiple lines
app/assets/javascripts/tree.js.coffee
@@ -35,3 +35,22 @@ $ -> @@ -35,3 +35,22 @@ $ ->
35 state = History.getState() 35 state = History.getState()
36 window.ajaxGet(state.url) 36 window.ajaxGet(state.url)
37 )(window) 37 )(window)
  38 +
  39 + # See if there are lines selected
  40 + # "#L12" and "#L34-56" supported
  41 + highlightBlobLines = ->
  42 + if window.location.hash isnt ""
  43 + matches = window.location.hash.match /\#L(\d+)(\-(\d+))?/
  44 + first_line = parseInt matches[1]
  45 + last_line = parseInt matches[3]
  46 +
  47 + unless isNaN first_line
  48 + last_line = first_line if isNaN last_line
  49 + $("#tree-content-holder .highlight .line").removeClass("hll")
  50 + $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
  51 + $("#L#{first_line}").ScrollTo()
  52 +
  53 + # Highlight the correct lines on load
  54 + highlightBlobLines()
  55 + # Highlight the correct lines when the hash part of the URL changes
  56 + $(window).on 'hashchange', highlightBlobLines
app/assets/stylesheets/gitlab_bootstrap/files.scss
@@ -132,39 +132,73 @@ @@ -132,39 +132,73 @@
132 * Code file 132 * Code file
133 */ 133 */
134 &.code { 134 &.code {
135 - padding:0;  
136 - td.code {  
137 - width: 100%;  
138 - .highlight {  
139 - margin-left: 55px;  
140 - overflow:auto;  
141 - overflow-y:hidden;  
142 - }  
143 - }  
144 - .highlight pre {  
145 - white-space: pre;  
146 - word-wrap:normal;  
147 - } 135 + padding: 0;
148 136
149 - table.highlighttable { 137 + table.lines {
150 border: none; 138 border: none;
151 - }  
152 - body.project-page table.highlighttable td { border: none }  
153 - table.highlighttable tr:hover { background:none;} 139 + box-shadow: none;
  140 + margin: 0px;
  141 + padding: 0px;
  142 + table-layout: fixed;
154 143
155 - table.highlighttable pre{  
156 - line-height:16px !important;  
157 - font-size:12px !important;  
158 - } 144 + pre {
  145 + background: none;
  146 + border: none;
  147 + font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  148 + font-size: 12px !important;
  149 + line-height: 16px !important;
  150 + margin: 0;
  151 + padding: 10px 0;
  152 + }
  153 + td {
  154 + border: none;
  155 + margin: 0;
  156 + padding: 0;
  157 + vertical-align: top;
  158 +
  159 + &:first-child {
  160 + background: #eee;
  161 + width: 50px;
  162 + }
  163 + &:last-child {
  164 + }
  165 + }
  166 + tr:hover {
  167 + background: none;
  168 + }
159 169
160 - table.highlighttable .linenodiv {  
161 - a { 170 + pre.line_numbers {
162 color: #666; 171 color: #666;
163 - }  
164 - pre { 172 + padding: 10px 6px 10px 0;
165 text-align: right; 173 text-align: right;
166 - padding-right: 4px;  
167 - color:#666; 174 +
  175 + a {
  176 + color: #666;
  177 +
  178 + i {
  179 + display: none;
  180 + font-size: 14px;
  181 + line-height: 14px;
  182 + }
  183 + &:hover i {
  184 + display: inherit;
  185 + }
  186 + }
  187 + }
  188 +
  189 + .highlight {
  190 + border-left: 1px solid #DEE2E3;
  191 + overflow: auto;
  192 + overflow-y: hidden;
  193 +
  194 + pre {
  195 + white-space: pre;
  196 + word-wrap: normal;
  197 +
  198 + .line {
  199 + padding: 0 10px;
  200 + }
  201 + }
168 } 202 }
169 } 203 }
170 } 204 }
app/assets/stylesheets/highlight/dark.scss
1 -.black .highlighttable {  
2 - td.linenos { border:none; }  
3 - pre { color: #eee }  
4 - .highlight { background: #333; border-left:1px solid #555; } 1 +.black .lines .highlight {
  2 + background: #333;
  3 + pre { color: #eee; }
5 4
6 - .hll { background-color: #ffffff } 5 + .hll { display: block; background-color: darken($hover, 65%) }
7 .c { color: #888888; font-style: italic } /* Comment */ 6 .c { color: #888888; font-style: italic } /* Comment */
8 .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 7 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
9 .k { color: #CDA869; font-weight: bold } /* Keyword */ 8 .k { color: #CDA869; font-weight: bold } /* Keyword */
@@ -22,43 +21,43 @@ @@ -22,43 +21,43 @@
22 .gs { font-weight: bold } /* Generic.Strong */ 21 .gs { font-weight: bold } /* Generic.Strong */
23 .gu { color: #606060 } /* Generic.Subheading */ 22 .gu { color: #606060 } /* Generic.Subheading */
24 .gt { color: #aa0000 } /* Generic.Traceback */ 23 .gt { color: #aa0000 } /* Generic.Traceback */
25 - .highlight .kc{font-weight:bold;} /* Keyword.Constant */  
26 - .highlight .kd{font-weight:bold;} /* Keyword.Declaration */  
27 - .highlight .kn{font-weight:bold;} /* Keyword.Namespace */  
28 - .highlight .kp{font-weight:bold;} /* Keyword.Pseudo */  
29 - .highlight .kr{font-weight:bold;} /* Keyword.Reserved */  
30 - .highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ 24 + .kc{font-weight:bold;} /* Keyword.Constant */
  25 + .kd{font-weight:bold;} /* Keyword.Declaration */
  26 + .kn{font-weight:bold;} /* Keyword.Namespace */
  27 + .kp{font-weight:bold;} /* Keyword.Pseudo */
  28 + .kr{font-weight:bold;} /* Keyword.Reserved */
  29 + .kt{color:#458;font-weight:bold;} /* Keyword.Type */
31 .m { color: #0000DD; font-weight: bold } /* Literal.Number */ 30 .m { color: #0000DD; font-weight: bold } /* Literal.Number */
32 .p { color: #eee; } 31 .p { color: #eee; }
33 .s { color: #0AD; background-color: transparent } /* Literal.String */ 32 .s { color: #0AD; background-color: transparent } /* Literal.String */
34 - .highlight .na{color:#008080;} /* Name.Attribute */  
35 - .highlight .nb{color:#0086B3;} /* Name.Builtin */  
36 - .highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */  
37 - .highlight .no{color:turquoise;} /* Name.Constant */  
38 - .highlight .ni{color:#800080;}  
39 - .highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */  
40 - .highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */  
41 - .highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */  
42 - .highlight .nt{color:#fc5;} /* Name.Tag */  
43 - .highlight .nv{color:#FA4;} /* Name.Variable */ 33 + .na{color:#008080;} /* Name.Attribute */
  34 + .nb{color:#0086B3;} /* Name.Builtin */
  35 + .nc{color:#ccc;font-weight:bold;} /* Name.Class */
  36 + .no{color:turquoise;} /* Name.Constant */
  37 + .ni{color:#800080;}
  38 + .ne{color:#900;font-weight:bold;} /* Name.Exception */
  39 + .nf{color:#ccc;font-weight:bold;} /* Name.Function */
  40 + .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
  41 + .nt{color:#fc5;} /* Name.Tag */
  42 + .nv{color:#FA4;} /* Name.Variable */
44 .py { color: #336699; font-weight: bold } /* Name.Property */ 43 .py { color: #336699; font-weight: bold } /* Name.Property */
45 .ow { color: #008800 } /* Operator.Word */ 44 .ow { color: #008800 } /* Operator.Word */
46 .w { color: #bbbbbb } /* Text.Whitespace */ 45 .w { color: #bbbbbb } /* Text.Whitespace */
47 .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */ 46 .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */
48 .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */ 47 .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */
49 - .highlight .mi {color:#099;} /* Literal.Number.Integer */ 48 + .mi {color:#099;} /* Literal.Number.Integer */
50 .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ 49 .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
51 .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */ 50 .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */
52 - .highlight .sc{color:#d14;} /* Literal.String.Char */ 51 + .sc{color:#d14;} /* Literal.String.Char */
53 .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */ 52 .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */
54 - .highlight .s2{color:orange;} /* Literal.String.Double */  
55 - .highlight .se{color:orange;} /* Literal.String.Escape */  
56 - .highlight .sh{color:orange;} /* Literal.String.Heredoc */  
57 - .highlight .si{color:orange;} /* Literal.String.Interpol */  
58 - .highlight .sx{color:orange;} /* Literal.String.Other */  
59 - .highlight .sr{color:orange;} /* Literal.String.Regex */  
60 - .highlight .s1{color:orange;} /* Literal.String.Single */  
61 - .highlight .ss{color:orange;} /* Literal.String.Symbol */ 53 + .s2{color:orange;} /* Literal.String.Double */
  54 + .se{color:orange;} /* Literal.String.Escape */
  55 + .sh{color:orange;} /* Literal.String.Heredoc */
  56 + .si{color:orange;} /* Literal.String.Interpol */
  57 + .sx{color:orange;} /* Literal.String.Other */
  58 + .sr{color:orange;} /* Literal.String.Regex */
  59 + .s1{color:orange;} /* Literal.String.Single */
  60 + .ss{color:orange;} /* Literal.String.Symbol */
62 .bp { color: #D58 } /* Name.Builtin.Pseudo */ 61 .bp { color: #D58 } /* Name.Builtin.Pseudo */
63 .vc { color: #336699 } /* Name.Variable.Class */ 62 .vc { color: #336699 } /* Name.Variable.Class */
64 .vg { color: #dd7700 } /* Name.Variable.Global */ 63 .vg { color: #dd7700 } /* Name.Variable.Global */
app/assets/stylesheets/highlight/white.scss
1 -table.highlighttable {  
2 - margin:0px;  
3 - padding:0px;  
4 - font-size:12px;  
5 - table-layout:fixed;  
6 - background: #EEE;  
7 - box-shadow: none;  
8 - border: none;  
9 - td.linenos {  
10 - background:#eee;  
11 - border-left:none;  
12 - }  
13 - td.code {  
14 - border-right:none;  
15 - }  
16 -}  
17 -  
18 -  
19 -td.code,  
20 -td.linenos{  
21 - padding:0;  
22 - margin:0;  
23 - border-top:0;  
24 - vertical-align:top;  
25 -}  
26 -  
27 -.highlighttable .highlight{  
28 - background:none;  
29 - padding:10px 0px 0px 10px;  
30 - margin-left:0px;  
31 - border-left: 1px solid #DEE2E3; 1 +.white .lines .highlight {
32 background: white; 2 background: white;
33 -}  
34 -  
35 -.linenodiv pre,  
36 -.highlighttable .highlight pre{  
37 - margin:0;  
38 - padding:0;  
39 - background:none;  
40 - border:none;  
41 -} 3 + pre { color: #333; }
42 4
43 -.linenodiv pre {  
44 - white-space:pre-line; 5 + .hll { display: block; background-color: $hover }
  6 + .c { color: #888888; font-style: italic } /* Comment */
  7 + .err { color: #a61717; background-color: #e3d2d2 } /* Error */
  8 + .k { color: #000000; font-weight: bold } /* Keyword */
  9 + .cm { color: #888888 } /* Comment.Multiline */
  10 + .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
  11 + .c1 { color: #888888 } /* Comment.Single */
  12 + .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
  13 + .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
  14 + .ge { font-style: italic } /* Generic.Emph */
  15 + .gr { color: #aa0000 } /* Generic.Error */
  16 + .gh { color: #303030 } /* Generic.Heading */
  17 + .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
  18 + .go { color: #888888 } /* Generic.Output */
  19 + .gp { color: #555555 } /* Generic.Prompt */
  20 + .gs { font-weight: bold } /* Generic.Strong */
  21 + .gu { color: #606060 } /* Generic.Subheading */
  22 + .gt { color: #aa0000 } /* Generic.Traceback */
  23 + .kc{font-weight:bold;} /* Keyword.Constant */
  24 + .kd{font-weight:bold;} /* Keyword.Declaration */
  25 + .kn{font-weight:bold;} /* Keyword.Namespace */
  26 + .kp{font-weight:bold;} /* Keyword.Pseudo */
  27 + .kr{font-weight:bold;} /* Keyword.Reserved */
  28 + .kt{color:#458;font-weight:bold;} /* Keyword.Type */
  29 + .m { color: #0000DD; font-weight: bold } /* Literal.Number */
  30 + .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
  31 + .na{color:#008080;} /* Name.Attribute */
  32 + .nb{color:#0086B3;} /* Name.Builtin */
  33 + .nc{color:#458;font-weight:bold;} /* Name.Class */
  34 + .no{color:#008080;} /* Name.Constant */
  35 + .ni{color:#800080;}
  36 + .ne{color:#900;font-weight:bold;} /* Name.Exception */
  37 + .nf{color:#900;font-weight:bold;} /* Name.Function */
  38 + .nn{color:#005;font-weight:bold;} /* Name.Namespace */
  39 + .nt{color:#000080;} /* Name.Tag */
  40 + .nv{color:#008080;} /* Name.Variable */
  41 + .py { color: #336699; font-weight: bold } /* Name.Property */
  42 + .ow { color: #008800 } /* Operator.Word */
  43 + .w { color: #bbbbbb } /* Text.Whitespace */
  44 + .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
  45 + .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
  46 + .mi {color:#099;} /* Literal.Number.Integer */
  47 + .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
  48 + .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
  49 + .sc{color:#d14;} /* Literal.String.Char */
  50 + .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
  51 + .s2{color:#d14;} /* Literal.String.Double */
  52 + .se{color:#d14;} /* Literal.String.Escape */
  53 + .sh{color:#d14;} /* Literal.String.Heredoc */
  54 + .si{color:#d14;} /* Literal.String.Interpol */
  55 + .sx{color:#d14;} /* Literal.String.Other */
  56 + .sr{color:#d14;} /* Literal.String.Regex */
  57 + .s1{color:#d14;} /* Literal.String.Single */
  58 + .ss{color:#d14;} /* Literal.String.Symbol */
  59 + .bp { color: #003388 } /* Name.Builtin.Pseudo */
  60 + .vc { color: #336699 } /* Name.Variable.Class */
  61 + .vg { color: #dd7700 } /* Name.Variable.Global */
  62 + .vi { color: #3333bb }
45 } 63 }
46 64
47 -td.linenos {  
48 - /*background:#F7F7F7;*/  
49 - color:#666;  
50 - padding:10px 0px 0px 10px;  
51 - float:left;  
52 - width:45px;  
53 - border-right: 1px solid #ccc;  
54 -  
55 -}  
56 -  
57 -td.code .highlight {  
58 - overflow: auto;  
59 -}  
60 -table.highlighttable pre{  
61 - padding:0;  
62 - margin:0;  
63 - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;  
64 - color: #333;  
65 - text-align:left;  
66 -}  
67 -  
68 -.git-empty .highlight {  
69 - pre{  
70 - padding:15px;  
71 - line-height:2.0;  
72 - margin:0;  
73 - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;  
74 - color: #333;  
75 - text-align:left;}  
76 - }  
77 -  
78 -.shadow{ 65 +.shadow {
79 -webkit-box-shadow:0 5px 15px #000; 66 -webkit-box-shadow:0 5px 15px #000;
80 -moz-box-shadow:0 5px 15px #000; 67 -moz-box-shadow:0 5px 15px #000;
81 box-shadow:0 5px 15px #000; 68 box-shadow:0 5px 15px #000;
82 } 69 }
83 -  
84 -.hll { background-color: #ffffff }  
85 -.c { color: #888888; font-style: italic } /* Comment */  
86 -.err { color: #a61717; background-color: #e3d2d2 } /* Error */  
87 -.k { color: #000000; font-weight: bold } /* Keyword */  
88 -.cm { color: #888888 } /* Comment.Multiline */  
89 -.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */  
90 -.c1 { color: #888888 } /* Comment.Single */  
91 -.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */  
92 -.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */  
93 -.ge { font-style: italic } /* Generic.Emph */  
94 -.gr { color: #aa0000 } /* Generic.Error */  
95 -.gh { color: #303030 } /* Generic.Heading */  
96 -.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */  
97 -.go { color: #888888 } /* Generic.Output */  
98 -.gp { color: #555555 } /* Generic.Prompt */  
99 -.gs { font-weight: bold } /* Generic.Strong */  
100 -.gu { color: #606060 } /* Generic.Subheading */  
101 -.gt { color: #aa0000 } /* Generic.Traceback */  
102 -.highlight .kc{font-weight:bold;} /* Keyword.Constant */  
103 -.highlight .kd{font-weight:bold;} /* Keyword.Declaration */  
104 -.highlight .kn{font-weight:bold;} /* Keyword.Namespace */  
105 -.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */  
106 -.highlight .kr{font-weight:bold;} /* Keyword.Reserved */  
107 -.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */  
108 -.m { color: #0000DD; font-weight: bold } /* Literal.Number */  
109 -.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */  
110 -.highlight .na{color:#008080;} /* Name.Attribute */  
111 -.highlight .nb{color:#0086B3;} /* Name.Builtin */  
112 -.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */  
113 -.highlight .no{color:#008080;} /* Name.Constant */  
114 -.highlight .ni{color:#800080;}  
115 -.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */  
116 -.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */  
117 -.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */  
118 -.highlight .nt{color:#000080;} /* Name.Tag */  
119 -.highlight .nv{color:#008080;} /* Name.Variable */  
120 -.py { color: #336699; font-weight: bold } /* Name.Property */  
121 -.ow { color: #008800 } /* Operator.Word */  
122 -.w { color: #bbbbbb } /* Text.Whitespace */  
123 -.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */  
124 -.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */  
125 -.highlight .mi {color:#099;} /* Literal.Number.Integer */  
126 -.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */  
127 -.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */  
128 -.highlight .sc{color:#d14;} /* Literal.String.Char */  
129 -.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */  
130 -.highlight .s2{color:#d14;} /* Literal.String.Double */  
131 -.highlight .se{color:#d14;} /* Literal.String.Escape */  
132 -.highlight .sh{color:#d14;} /* Literal.String.Heredoc */  
133 -.highlight .si{color:#d14;} /* Literal.String.Interpol */  
134 -.highlight .sx{color:#d14;} /* Literal.String.Other */  
135 -.highlight .sr{color:#d14;} /* Literal.String.Regex */  
136 -.highlight .s1{color:#d14;} /* Literal.String.Single */  
137 -.highlight .ss{color:#d14;} /* Literal.String.Symbol */  
138 -.bp { color: #003388 } /* Name.Builtin.Pseudo */  
139 -.vc { color: #336699 } /* Name.Variable.Class */  
140 -.vg { color: #dd7700 } /* Name.Variable.Global */  
141 -.vi { color: #3333bb }  
app/views/tree/blob/_text.html.haml
@@ -10,6 +10,6 @@ @@ -10,6 +10,6 @@
10 - unless blob.empty? 10 - unless blob.empty?
11 %div{class: current_user.dark_scheme ? "black" : "white"} 11 %div{class: current_user.dark_scheme ? "black" : "white"}
12 = preserve do 12 = preserve do
13 - = raw blob.colorize(options: { linenos: true, lineanchors: :line, anchorlinenos: true }) 13 + = raw blob.colorize(formatter: :gitlab)
14 - else 14 - else
15 %h4.nothing_here_message Empty file 15 %h4.nothing_here_message Empty file