Project

General

Profile

Feature #43678 » 0002-Replace-hard-coded-left-border-left-and-top-CSS-prop.patch

Go MAEDA, 2026-01-25 06:08

View differences:

app/views/gantts/_chart.html.erb
119 119
        <% months_height = (show_weeks ? header_height : header_height + g_height) %>
120 120
        <% gantt.months.times do %>
121 121
          <% width = (((month_f >> 1) - month_f) * zoom - 1).to_i %>
122
          <% month_style = +"left: #{left}px;" %>
122
          <% month_style = +"inset-inline-start: #{left}px;" %>
123 123
          <% month_style << "width: #{width}px;" %>
124 124
          <% month_style << "height: #{months_height}px;" %>
125 125
          <%= content_tag(:div, style: month_style, class: "gantt_hdr") do %>
......
139 139
          <% else %>
140 140
            <% week_f = gantt.date_from + (7 - gantt.date_from.cwday + 1) %>
141 141
            <% width = (7 - gantt.date_from.cwday + 1) * zoom - 1 %>
142
            <% gap_style = +"left: #{left}px;" %>
143
            <% gap_style << "top: 19px;" %>
142
            <% gap_style = +"inset-inline-start: #{left}px;" %>
143
            <% gap_style << "inset-block-start: 19px;" %>
144 144
            <% gap_style << "width: #{width}px;" %>
145 145
            <% gap_style << "height: #{weeks_height}px;" %>
146 146
            <%= content_tag(:div, '&nbsp;'.html_safe, style: gap_style, class: "gantt_hdr") %>
......
148 148
          <% end %>
149 149
          <% while week_f <= gantt.date_to %>
150 150
            <% width = ((week_f + 6 <= gantt.date_to) ? 7 * zoom - 1 : (gantt.date_to - week_f + 1) * zoom - 1).to_i %>
151
            <% week_style = +"left: #{left}px;" %>
152
            <% week_style << "top: 19px;" %>
151
            <% week_style = +"inset-inline-start: #{left}px;" %>
152
            <% week_style << "inset-block-start: 19px;" %>
153 153
            <% week_style << "width: #{width}px;" %>
154 154
            <% week_style << "height: #{weeks_height}px;" %>
155 155
            <%= content_tag(:div, style: week_style, class: "gantt_hdr") do %>
......
169 169
          <% day_num = gantt.date_from %>
170 170
          <% (gantt.date_to - gantt.date_from + 1).to_i.times do %>
171 171
            <% width = zoom - 1 %>
172
            <% day_style = +"left:#{left}px;" %>
173
            <% day_style << "top:37px;" %>
172
            <% day_style = +"inset-inline-start:#{left}px;" %>
173
            <% day_style << "inset-block-start:37px;" %>
174 174
            <% day_style << "width:#{width}px;" %>
175 175
            <% day_style << "height:#{days_height}px;" %>
176 176
            <% day_style << "font-size:0.7em;" %>
......
192 192
          <% days_top = (show_day_num ? 55 : 37) %>
193 193
          <% (gantt.date_from..gantt.date_to).each do |g_date| %>
194 194
            <% width = zoom - 1 %>
195
            <% day_style = +"left: #{left}px;" %>
196
            <% day_style << "top: #{days_top}px;" %>
195
            <% day_style = +"inset-inline-start: #{left}px;" %>
196
            <% day_style << "inset-block-start: #{days_top}px;" %>
197 197
            <% day_style << "width: #{width}px;" %>
198 198
            <% day_style << "height: #{days_height}px;" %>
199 199
            <% day_style << "font-size:0.7em;" %>
......
215 215
          <% today_left = (((User.current.today - gantt.date_from + 1) * zoom).floor - 1).to_i %>
216 216
          <% today_style = +"position: absolute;" %>
217 217
          <% today_style << "height: #{g_height}px;" %>
218
          <% today_style << "top: #{headers_height + 1}px;" %>
219
          <% today_style << "left: #{today_left}px;" %>
218
          <% today_style << "inset-block-start: #{headers_height + 1}px;" %>
219
          <% today_style << "inset-inline-start: #{today_left}px;" %>
220 220
          <% today_style << "width:10px;" %>
221
          <% today_style << "border-left: 1px dashed red;" %>
221
          <% today_style << "border-inline-start: 1px dashed red;" %>
222 222
          <%= content_tag(:div, '&nbsp;'.html_safe, style: today_style, id: 'today_line') %>
223 223
        <% end %>
224 224

  
225 225
        <%
226 226
          draw_area_style = +"position: absolute;"
227 227
          draw_area_style << "height: #{g_height}px;"
228
          draw_area_style << "top: #{headers_height + 1}px;"
229
          draw_area_style << 'left: 0px;'
228
          draw_area_style << "inset-block-start: #{headers_height + 1}px;"
229
          draw_area_style << 'inset-inline-start: 0px;'
230 230
          draw_area_style << "width: #{g_width - 1}px;"
231 231
        %>
232 232
        <%= content_tag(:div, '', style: draw_area_style, id: "gantt_draw_area", data: {'gantt--chart-target': 'drawArea'}) %>
lib/redmine/helpers/gantt.rb
359 359
          data_options = {}
360 360
          data_options[:collapse_expand] = "issue-#{issue.id}"
361 361
          data_options[:number_of_rows] = number_of_rows
362
          style = "position: absolute;top: #{options[:top]}px; font-size: 0.8em;"
362
          style = "position: absolute;inset-block-start: #{options[:top]}px; font-size: 0.8em;"
363 363
          content =
364 364
            view.content_tag(
365 365
              :div, view.column_content(options[:column], issue),
......
827 827
            params[:indent] += 18
828 828
          end
829 829
        end
830
        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
830
        style = "position: absolute;inset-block-start:#{params[:top]}px;inset-inline-start:#{params[:indent]}px;"
831 831
        style += "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
832 832
        tag_options[:style] = style
833 833
        output = view.content_tag(:div, content, tag_options)
......
890 890
        if coords[:bar_start] && coords[:bar_end]
891 891
          width = coords[:bar_end] - coords[:bar_start] - 2
892 892
          style = +""
893
          style << "top:#{params[:top]}px;"
894
          style << "left:#{coords[:bar_start]}px;"
893
          style << "inset-block-start:#{params[:top]}px;"
894
          style << "inset-inline-start:#{coords[:bar_start]}px;"
895 895
          style << "width:#{width}px;"
896 896
          html_id = "task-todo-issue-#{object.id}" if object.is_a?(Issue)
897 897
          html_id = "task-todo-version-#{object.id}" if object.is_a?(Version)
......
910 910
          if coords[:bar_late_end]
911 911
            width = coords[:bar_late_end] - coords[:bar_start] - 2
912 912
            style = +""
913
            style << "top:#{params[:top]}px;"
914
            style << "left:#{coords[:bar_start]}px;"
913
            style << "inset-block-start:#{params[:top]}px;"
914
            style << "inset-inline-start:#{coords[:bar_start]}px;"
915 915
            style << "width:#{width}px;"
916 916
            output << view.content_tag(:div, '&nbsp;'.html_safe,
917 917
                                       :style => style,
......
921 921
          if coords[:bar_progress_end]
922 922
            width = coords[:bar_progress_end] - coords[:bar_start] - 2
923 923
            style = +""
924
            style << "top:#{params[:top]}px;"
925
            style << "left:#{coords[:bar_start]}px;"
924
            style << "inset-block-start:#{params[:top]}px;"
925
            style << "inset-inline-start:#{coords[:bar_start]}px;"
926 926
            style << "width:#{width}px;"
927 927
            html_id = "task-done-issue-#{object.id}" if object.is_a?(Issue)
928 928
            html_id = "task-done-version-#{object.id}" if object.is_a?(Version)
......
937 937
        if markers
938 938
          if coords[:start]
939 939
            style = +""
940
            style << "top:#{params[:top]}px;"
941
            style << "left:#{coords[:start]}px;"
940
            style << "inset-block-start:#{params[:top]}px;"
941
            style << "inset-inline-start:#{coords[:start]}px;"
942 942
            style << "width:15px;"
943 943
            output << view.content_tag(:div, '&nbsp;'.html_safe,
944 944
                                       :style => style,
......
947 947
          end
948 948
          if coords[:end]
949 949
            style = +""
950
            style << "top:#{params[:top]}px;"
951
            style << "left:#{coords[:end]}px;"
950
            style << "inset-block-start:#{params[:top]}px;"
951
            style << "inset-inline-start:#{coords[:end]}px;"
952 952
            style << "width:15px;"
953 953
            output << view.content_tag(:div, '&nbsp;'.html_safe,
954 954
                                       :style => style,
......
959 959
        # Renders the label on the right
960 960
        if label
961 961
          style = +""
962
          style << "top:#{params[:top]}px;"
963
          style << "left:#{(coords[:bar_end] || 0) + 8}px;"
962
          style << "inset-block-start:#{params[:top]}px;"
963
          style << "inset-inline-start:#{(coords[:bar_end] || 0) + 8}px;"
964 964
          style << "width:15px;"
965 965
          output << view.content_tag(:div, label,
966 966
                                     :style => style,
......
977 977
                                :class => 'toggle-selection')
978 978
          style = +""
979 979
          style << "position: absolute;"
980
          style << "top:#{params[:top]}px;"
981
          style << "left:#{coords[:bar_start]}px;"
980
          style << "inset-block-start:#{params[:top]}px;"
981
          style << "inset-inline-start:#{coords[:bar_start]}px;"
982 982
          style << "width:#{coords[:bar_end] - coords[:bar_start]}px;"
983 983
          style << "height:12px;"
984 984
          output << view.content_tag(:div, s.html_safe,
test/functional/gantts_controller_test.rb
228 228

  
229 229
    # eCookbook
230 230
    assert_subject_row('div.project-name', row: '0', text: project.name)
231
    assert_chart_row('div.task.project.task_todo', row: '0', style_substring: 'left:0px;width:138px')
231
    assert_chart_row('div.task.project.task_todo', row: '0', style_substring: 'inset-inline-start:0px;width:138px')
232 232

  
233 233
    assert_issue_row(3, 'Bug #3', row: '1')
234
    assert_chart_row('div.task.leaf.task_todo', row: '1', style_substring: 'left:0px;width:38px')
234
    assert_chart_row('div.task.leaf.task_todo', row: '1', style_substring: 'inset-inline-start:0px;width:38px')
235 235

  
236 236
    assert_issue_row(7, 'Bug #7', row: '2')
237
    assert_chart_row('div.task.leaf.task_todo', row: '2', style_substring: 'left:16px;width:42px')
237
    assert_chart_row('div.task.leaf.task_todo', row: '2', style_substring: 'inset-inline-start:16px;width:42px')
238 238

  
239 239
    assert_issue_row(1, 'Bug #1', row: '3')
240
    assert_chart_row('div.task.leaf.task_todo', row: '3', style_substring: 'left:52px;width:46px')
240
    assert_chart_row('div.task.leaf.task_todo', row: '3', style_substring: 'inset-inline-start:52px;width:46px')
241 241

  
242 242
    # Version 1.0
243 243
    assert_subject_row('div#version-2', row: '4', text: '1.0')
244
    assert_chart_row('div.task.version', row: '4', style_substring: 'left:48px;width:90px')
244
    assert_chart_row('div.task.version', row: '4', style_substring: 'inset-inline-start:48px;width:90px')
245 245

  
246 246
    assert_issue_row(2, 'Feature request #2', row: '5')
247
    assert_chart_row('div.task.leaf.task_todo', row: '5', style_substring: 'left:48px;width:90px')
247
    assert_chart_row('div.task.leaf.task_todo', row: '5', style_substring: 'inset-inline-start:48px;width:90px')
248 248

  
249 249
    # Private child of eCookbook
250 250
    assert_subject_row(
......
252 252
      row: '6',
253 253
      text: projects(:projects_005).name
254 254
    )
255
    assert_chart_row('div.task.project.task_todo', row: '6', style_substring: 'left:56px;width:6px')
255
    assert_chart_row('div.task.project.task_todo', row: '6', style_substring: 'inset-inline-start:56px;width:6px')
256 256

  
257 257
    assert_issue_row(6, 'Bug #6', row: '7')
258
    assert_chart_row('div.task.leaf.task_todo', row: '7', style_substring: 'left:56px;width:6px')
258
    assert_chart_row('div.task.leaf.task_todo', row: '7', style_substring: 'inset-inline-start:56px;width:6px')
259 259

  
260 260
    assert_issue_row(9, 'Bug #9', row: '8')
261
    assert_chart_row('div.task.leaf.task_todo', row: '8', style_substring: 'left:56px;width:6px')
261
    assert_chart_row('div.task.leaf.task_todo', row: '8', style_substring: 'inset-inline-start:56px;width:6px')
262 262

  
263 263
    assert_issue_row(10, 'Bug #10', row: '9')
264
    assert_chart_row('div.task.leaf.task_todo', row: '9', style_substring: 'left:56px;width:6px')
264
    assert_chart_row('div.task.leaf.task_todo', row: '9', style_substring: 'inset-inline-start:56px;width:6px')
265 265
    assert_select 'div.task[id=?][data-rels*=9]', 'task-todo-issue-10'
266 266

  
267 267
    # eCookbook Subproject1
......
303 303

  
304 304
    # eCookbook
305 305
    assert_subject_row('div.project-name', row: '0', text: projects(:projects_001).name)
306
    assert_chart_row('div.task.project.task_todo', row: '0', style_substring: 'left:0px;width:258px')
306
    assert_chart_row('div.task.project.task_todo', row: '0', style_substring: 'inset-inline-start:0px;width:258px')
307 307

  
308 308
    # Private child of eCookbook
309 309
    assert_subject_row(
......
311 311
      row: '1',
312 312
      text: project.name
313 313
    )
314
    assert_chart_row('div.task.project.task_todo', row: '1', style_substring: 'left:176px;width:6px')
314
    assert_chart_row('div.task.project.task_todo', row: '1', style_substring: 'inset-inline-start:176px;width:6px')
315 315

  
316 316
    # Bug #6
317 317
    assert_issue_row(6, 'Bug #6', row: '2')
318
    assert_chart_row('div.task.leaf.task_todo', row: '2', style_substring: 'left:176px;width:6px')
318
    assert_chart_row('div.task.leaf.task_todo', row: '2', style_substring: 'inset-inline-start:176px;width:6px')
319 319

  
320 320
    # Bug #9
321 321
    assert_issue_row(9, 'Bug #9', row: '3')
322
    assert_chart_row('div.task.leaf.task_todo', row: '3', style_substring: 'left:176px;width:6px')
322
    assert_chart_row('div.task.leaf.task_todo', row: '3', style_substring: 'inset-inline-start:176px;width:6px')
323 323

  
324 324
    # Bug #10
325 325
    assert_issue_row(10, 'Bug #10', row: '4')
326
    assert_chart_row('div.task.leaf.task_todo', row: '4', style_substring: 'left:176px;width:6px')
326
    assert_chart_row('div.task.leaf.task_todo', row: '4', style_substring: 'inset-inline-start:176px;width:6px')
327 327

  
328 328
    assert_select 'div.task[id=?][data-rels*=9]', 'task-todo-issue-10'
329 329
  end
test/unit/lib/redmine/helpers/gantt_test.rb
135 135
    setup_subjects
136 136
    @output_buffer = @gantt.subjects
137 137
    assert_select "div.project-name a", /#{@project.name}/
138
    assert_select 'div.project-name[style*="left:4px"]'
138
    assert_select 'div.project-name[style*="inset-inline-start:4px"]'
139 139
  end
140 140

  
141 141
  test "#subjects version should be rendered" do
142 142
    setup_subjects
143 143
    @output_buffer = @gantt.subjects
144 144
    assert_select "div.version-name a", /#{@version.name}/
145
    assert_select 'div.version-name[style*="left:24px"]'
145
    assert_select 'div.version-name[style*="inset-inline-start:24px"]'
146 146
  end
147 147

  
148 148
  test "#subjects version without assigned issues should not be rendered" do
......
160 160
    @output_buffer = @gantt.subjects
161 161
    assert_select "div.issue-subject", /#{@issue.subject}/
162 162
    # subject 62px: 44px + 18px(collapse/expand icon's width)
163
    assert_select 'div.issue-subject[style*="left:62px"]'
163
    assert_select 'div.issue-subject[style*="inset-inline-start:62px"]'
164 164
  end
165 165

  
166 166
  test "#subjects issue assigned to a shared version of another project should be rendered" do
......
205 205
                        )
206 206
    @output_buffer = @gantt.subjects
207 207
    # parent task 44px
208
    assert_select 'div.issue-subject[style*="left:44px"]', /#{@issue.subject}/
208
    assert_select 'div.issue-subject[style*="inset-inline-start:44px"]', /#{@issue.subject}/
209 209
    # children 64px
210
    assert_select 'div.issue-subject[style*="left:64px"]', /child1/
210
    assert_select 'div.issue-subject[style*="inset-inline-start:64px"]', /child1/
211 211
    # children 76px: 64px + 18px(collapse/expand icon's width)
212
    assert_select 'div.issue-subject[style*="left:82px"]', /child2/
212
    assert_select 'div.issue-subject[style*="inset-inline-start:82px"]', /child2/
213 213
    # grandchild 96px: 84px + 18px(collapse/expand icon's width)
214
    assert_select 'div.issue-subject[style*="left:102px"]', /grandchild/, @output_buffer
214
    assert_select 'div.issue-subject[style*="inset-inline-start:102px"]', /grandchild/, @output_buffer
215 215
  end
216 216

  
217 217
  test "#lines" do
......
319 319
    create_gantt
320 320
    @output_buffer = @gantt.subject('subject', :format => :html, :indent => 40)
321 321
    # subject 52px: 40px(indent) + 12px(collapse/expand icon's width)
322
    assert_select 'div[style*="left:58px"]'
322
    assert_select 'div[style*="inset-inline-start:58px"]'
323 323
  end
324 324

  
325 325
  test "#line_for_project" do
......
353 353
  test "#line todo line should start from the starting point on the left" do
354 354
    create_gantt
355 355
    @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
356
    assert_select 'div.task_todo[style*="left:28px"]', 1
356
    assert_select 'div.task_todo[style*="inset-inline-start:28px"]', 1
357 357
  end
358 358

  
359 359
  test "#line todo line should appear if it ends on the leftmost date in the gantt" do
......
361 361
    [gantt_start - 1, gantt_start].each do |start_date|
362 362
      @output_buffer = @gantt.line(start_date, gantt_start, 30, false, 'line', :format => :html, :zoom => 4)
363 363
      # the leftmost date (Date.today - 14 days)
364
      assert_select 'div.task_todo[style*="left:0px"]', 1, @output_buffer
364
      assert_select 'div.task_todo[style*="inset-inline-start:0px"]', 1, @output_buffer
365 365
      assert_select 'div.task_todo[style*="width:2px"]', 1, @output_buffer
366 366
    end
367 367
  end
......
371 371
    [gantt_end, gantt_end + 1].each do |end_date|
372 372
      @output_buffer = @gantt.line(gantt_end, end_date, 30, false, 'line', :format => :html, :zoom => 4)
373 373
      # the rightmost date (Date.today + 14 days)
374
      assert_select 'div.task_todo[style*="left:112px"]', 1, @output_buffer
374
      assert_select 'div.task_todo[style*="inset-inline-start:112px"]', 1, @output_buffer
375 375
      assert_select 'div.task_todo[style*="width:2px"]', 1, @output_buffer
376 376
    end
377 377
  end
......
385 385
  test "#line late line should start from the starting point on the left" do
386 386
    create_gantt
387 387
    @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
388
    assert_select 'div.task_late[style*="left:28px"]', 1
388
    assert_select 'div.task_late[style*="inset-inline-start:28px"]', 1
389 389
  end
390 390

  
391 391
  test "#line late line should be the total delayed width" do
......
411 411
  test "#line done line should start from the starting point on the left" do
412 412
    create_gantt
413 413
    @output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
414
    assert_select 'div.task_done[style*="left:28px"]', 1
414
    assert_select 'div.task_done[style*="inset-inline-start:28px"]', 1
415 415
  end
416 416

  
417 417
  test "#line done line should be the width for the done ratio" do
......
437 437
  test "#line done line should not be the total done width if the gantt starts after start date" do
438 438
    create_gantt
439 439
    @output_buffer = @gantt.line(today - 16, today - 2, 30, false, 'line', :format => :html, :zoom => 4)
440
    assert_select 'div.task_done[style*="left:0px"]', 1
440
    assert_select 'div.task_done[style*="inset-inline-start:0px"]', 1
441 441
    assert_select 'div.task_done[style*="width:8px"]', 1
442 442
  end
443 443

  
......
445 445
    create_gantt
446 446
    @output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
447 447
    assert_select "div.starting", 1
448
    assert_select 'div.starting[style*="left:28px"]', 1
448
    assert_select 'div.starting[style*="inset-inline-start:28px"]', 1
449 449
    # starting marker on the leftmost boundary of the gantt
450 450
    @output_buffer = @gantt.line(gantt_start, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
451
    assert_select 'div.starting[style*="left:0px"]', 1
451
    assert_select 'div.starting[style*="inset-inline-start:0px"]', 1
452 452
  end
453 453

  
454 454
  test "#line starting marker should not appear if the start date is before gantt start date" do
......
461 461
    create_gantt
462 462
    @output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
463 463
    assert_select "div.ending", 1
464
    assert_select 'div.ending[style*="left:88px"]', 1
464
    assert_select 'div.ending[style*="inset-inline-start:88px"]', 1
465 465
    # ending marker on the rightmost boundary of the gantt
466 466
    @output_buffer = @gantt.line(today - 7, gantt_end, 30, true, 'line', :format => :html, :zoom => 4)
467
    assert_select 'div.ending[style*="left:116px"]', 1
467
    assert_select 'div.ending[style*="inset-inline-start:116px"]', 1
468 468
  end
469 469

  
470 470
  test "#line ending marker should not appear if the end date is before gantt start date" do
(3-3/5)