From 3a23ddac1f8acaeaf5cdb4292b137b8667712f0f Mon Sep 17 00:00:00 2001 From: Go MAEDA Date: Thu, 29 Jan 2026 07:36:07 +0000 Subject: [PATCH] Update Gantt collapse/expand handler to use CSS logical properties (#43678). Patch by Go MAEDA (user:maeda). git-svn-id: https://svn.redmine.org/redmine/trunk@24384 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- .../controllers/gantt/subjects_controller.js | 36 +++++++++++++------ lib/redmine/helpers/gantt.rb | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/javascript/controllers/gantt/subjects_controller.js b/app/javascript/controllers/gantt/subjects_controller.js index 8fdbb0954..83062989c 100644 --- a/app/javascript/controllers/gantt/subjects_controller.js +++ b/app/javascript/controllers/gantt/subjects_controller.js @@ -17,8 +17,8 @@ export default class extends Controller { handleEntryClick(event) { const iconExpander = event.currentTarget const $subject = this.$(iconExpander.parentElement) - const subjectLeft = - parseInt($subject.css("left"), 10) + parseInt(iconExpander.offsetWidth, 10) + const subjectInlineStart = + this.#readInlineStart($subject) + parseInt(iconExpander.offsetWidth, 10) let targetShown = null let targetTop = 0 @@ -36,16 +36,16 @@ export default class extends Controller { const barsSelector = `#gantt_area form > div[data-collapse-expand='${json.obj_id}'][data-number-of-rows='${numberOfRows}']` const selectedColumnsSelector = `td.gantt_selected_column div[data-collapse-expand='${json.obj_id}'][data-number-of-rows='${numberOfRows}']` - if (outOfHierarchy || parseInt($element.css("left"), 10) <= subjectLeft) { + if (outOfHierarchy || this.#readInlineStart($element) <= subjectInlineStart) { outOfHierarchy = true if (targetShown === null) return false - const newTopVal = parseInt($element.css("top"), 10) + totalHeight * (targetShown ? -1 : 1) + const newTopVal = this.#readBlockStart($element) + totalHeight * (targetShown ? -1 : 1) - $element.css("top", newTopVal) + this.#setBlockStart($element, newTopVal) this.$([barsSelector, selectedColumnsSelector].join()).each((__, el) => { - this.$(el).css("top", newTopVal) + this.#setBlockStart(this.$(el), newTopVal) }) return true @@ -55,7 +55,7 @@ export default class extends Controller { if (targetShown === null) { targetShown = isShown - targetTop = parseInt($element.css("top"), 10) + targetTop = this.#readBlockStart($element) totalHeight = 0 } @@ -64,7 +64,7 @@ export default class extends Controller { const $task = this.$(task) if (!isShown && willOpen) { - $task.css("top", targetTop + totalHeight) + this.#setBlockStart($task, targetTop + totalHeight) } if (!$task.hasClass("tooltip")) { $task.toggle(willOpen) @@ -75,13 +75,13 @@ export default class extends Controller { const $attr = this.$(attr) if (!isShown && willOpen) { - $attr.css("top", targetTop + totalHeight) + this.#setBlockStart($attr, targetTop + totalHeight) } $attr.toggle(willOpen) }) if (!isShown && willOpen) { - $element.css("top", targetTop + totalHeight) + this.#setBlockStart($element, targetTop + totalHeight) } this.#setIconState($element, willOpen) @@ -93,6 +93,22 @@ export default class extends Controller { this.dispatch("toggle-tree", { bubbles: true }) } + #readInlineStart(el) { + const node = el.jquery ? el[0] : el + return parseFloat(window.getComputedStyle(node).getPropertyValue("inset-inline-start")) + } + + #readBlockStart(el) { + const node = el.jquery ? el[0] : el + return parseFloat(window.getComputedStyle(node).getPropertyValue("inset-block-start")) + } + + #setBlockStart(el, value) { + const node = el.jquery ? el[0] : el + const px = typeof value === "number" ? `${value}px` : value + node.style.setProperty("inset-block-start", px) + } + #setIconState(element, open) { const $element = element.jquery ? element : this.$(element) const expander = $element.find(".expander") diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb index 50864fb7d..0753c3209 100644 --- a/lib/redmine/helpers/gantt.rb +++ b/lib/redmine/helpers/gantt.rb @@ -817,7 +817,7 @@ module Redmine end if has_children content = view.content_tag(:span, - view.sprite_icon('angle-down').html_safe, + view.sprite_icon('angle-down', rtl: true).html_safe, :class => 'icon icon-expanded expander', :data => {:action => 'click->gantt--subjects#handleEntryClick'}) + content tag_options[:class] += ' open'