Неожиданное масштабирование в экспериментальном компоненте PhotoSwipeLightbox нарушает пропорции исходного изображения

Новый экспериментальный PhotoSwipeLightbox (siteSettings.experimental_lightbox) содержит ошибки, когда ссылка на изображение существует в Discourse Solved или в компоненте загрузки в admin/config/logo, а также в местах, где отсутствует размеченный HTML-тег [img].

Корень проблемы заключается в том, что PhotoSwipeLightbox требует ширины и высоты уже загруженного изображения, тогда как Discourse Solved и компонент загрузки не имеют этих атрибутов.

Без этих атрибутов изображение растягивается, чтобы заполнить окно браузера, что приводит к искажению, как показано на приложенном рисунке.

Этот коммит добавляет механизм предварительной загрузки для изображений без размеров, чтобы получить их размеры, так что они могут отображаться корректно.

2 лайка

Спасибо за сообщение об этой проблеме и предоставление исправления.

Я добавил несколько комментариев и предложений к PR, но в целом, думаю, нам нужен подобный механизм резервного копирования для обработки пограничных случаев.

Ок, спасибо. Как только освобожусь, я добавлю свои комментарии.

  context "когда отсутствуют атрибуты данных" do
    it "предзагружает изображения и устанавливает размеры" do
      upload_1.update(width: 400, height: 300)
      post.update(
        cooked:
          "<p><a href=\"#{upload_1.url}\" class=\"lightbox\" data-download-href=\"#{upload_1.url}\">[image]</a></p>",
      )

      topic_page.visit_topic(topic)
      lightbox_link = find("#post_1 a.lightbox")
      lightbox_link.click

      expect(lightbox).to be_visible

      expect(lightbox_link["data-target-width"]).to eq(upload_1.width.to_s)
      expect(lightbox_link["data-target-height"]).to eq(upload_1.height.to_s)
    end
  end

Я добавляю это в lightbox_spec.rb как юнит-тест для изображений без размеров. Всё выглядит нормально?

1 лайк

Также я внес некоторые изменения в логику определения типа, чтобы обрабатывать случаи, когда метаданные присутствуют, но не содержат информацию о размере (например, компонент загрузки).

const missingMetaData = !item
    .querySelector(".meta")
    ?.textContent.trim()
    .split(/x|×/)
    .every((v) => v && +v > 0);
1 лайк

Спасибо за работу над этим и за ответ на ревью PR. Я уже объединил это.

1 лайк

@davidb Похоже, что в одном из последних коммитов компонента lightbox есть ошибка, из-за которой компонент не запускается в Discourse Solved и подобных местах после слияния моего PR.

Проблема может быть связана с этим коммитом:

FEATURE: allow quoting an image from the lightbox by SamSaffron · Pull Request #36156 · discourse/discourse · GitHub.

Я не до конца уверен, действительно ли этот PR вызывает сбой.

Воспроизвести ошибку можно прямо сейчас здесь:

Например, нажав на [IMG_6085] в цитате onebox или открыв ссылку и кликнув по изображению ответа в компоненте Discourse Solved на указанной странице. Изначальное поведение — открытие lightbox, но сейчас ничего не происходит.

В консоли отображается ошибка: Uncaught TypeError: Cannot read properties of null (reading 'getAttribute').

Связанный код:

// это гарантирует, что обрезанные изображения (например, в сетке) не вызовут дрожания при закрытии
data.thumbCropped = true;

data.src = data.src || el.getAttribute("data-large-src");
-> data.origSrc = imgEl.getAttribute("data-orig-src");
data.title = el.title || imgEl.alt || imgEl.title;

Возможно, изменение кода следующим образом решит проблему:

data.origSrc = imgEl?.getAttribute("data-orig-src") || el.getAttribute("data-orig-src") || null;

data.base62SHA1 =
    imgEl?.getAttribute("data-base62-sha1") || el.getAttribute("data-base62-sha1") || null;

data.targetWidth =
    el.getAttribute("data-target-width") || imgEl?.getAttribute("width") || null;
data.targetHeight =
    el.getAttribute("data-target-height") || imgEl?.getAttribute("height") || null;

Исправление через PR уже применено здесь:

2 лайка