Встроенные предпросмотры PDF

Отлично! Спасибо @Johani. Могу подтвердить, что теперь это работает во всех трёх браузерах.

4 лайка

Отлично — это серьёзные улучшения, и для их достижения проделана огромная работа. Спасибо, что прислушались к нам, немного назойливым сообщникам из мира самохостинга!

Теперь компонент работает с загрузками в S3?

3 лайка

Я не пробовал, но это должно работать, если ваш бакет настроен правильно. Этот компонент отправляет запрос для загрузки PDF.

Такие запросы, выполняемые в JavaScript, блокируются, если источник не имеет права доступа к файлу. В результате возникает ошибка CORS. Если вы проверите консоль, то, скорее всего, увидите что-то вроде этого.

image

Сам компонент мало что может сделать в этой ситуации. Всё должно быть настроено в конфигурации вашего S3. Источник — ваш домен Discourse — должен иметь разрешение на выполнение таких запросов, чтобы избежать проблем с CORS.

9 лайков

Спасибо! Я вскоре снова решительно нырну в S3.

Ещё одно предложение: табуляция при наличии пробела перед именем файла

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

Возможно, настройку компонента стоит изменить на «Какое поведение по умолчанию вы хотите?», и если в имени файла есть пробел, будет применяться альтернативный вариант.

Или, в качестве альтернативы, можно спросить, что должен делать пробел: отображать внутри страницы / открывать во вкладке / загружать файл.

2 лайка

Ааарг! Chrome снова показывает только серые квадраты. FF и Safari в порядке.

3 лайка

Отправляет ли этот компонент темы PDF-файл внешнему интерпретатору?
У меня включена функция «Защищенные медиа», так как я хочу избежать загрузки файлов внешним сервисом.

1 лайк

Я выяснил, что это происходит из-за следующего кода:

<a class="attachment pdf-attachment" href="...pdf">doc.pdf
  <iframe src="blob:..." height="500" loading="lazy" class="pdf-preview">
  </iframe>
</a>

Если заменить указанный код на следующий:

<a class="attachment pdf-attachment" href="...pdf">doc.pdf</a>
<iframe src="blob:..." height="500" loading="lazy" class="pdf-preview"></iframe>

то всё заработает.
Но я не уверен, как исправить это в существующем коде.

5 лайков

@Johani
Ошибка связана со следующим кодом, строки 34–41:

        const setUpPreviewType = (pdf) => {
          if (previewMode === "Inline") {
            const preview = createPreviewElement();
            pdf.classList.add("pdf-attachment");
            pdf.append(preview);

            return preview;
          }
4 лайка

Это решение, похоже, работает во всех браузерах.

4 лайка

pdf.parentNode.append(preview); вроде бы решает проблему (но в случае нескольких PDF-файлов превью отображаются под всеми ссылками, а не под каждой из них)

3 лайка

Но если родительский узел — это абзац, то это не должно быть проблемой, так как ссылка и iframe будут находиться внутри тега абзаца.

Чтобы обойти эту проблему, просто добавьте пустую строку между вложениями:

[doc1.pdf|attachment](...)

[doc2.pdf|attachment](...)

И с вашим решением предпросмотр PDF будет корректно отображаться и в Chrome.

3 лайка

Я только что внес несколько изменений.

Да, это имеет больше смысла, чем игнорирование файла. Вот как всё будет работать после обновления.

  1. Если вы установите настройку в значение «Новая вкладка», компонент не будет добавлять превью в сообщениях. При клике на ссылку PDF откроется в новой вкладке.

  2. Если вы установите настройку в значение «Встроенно», компонент будет по умолчанию добавлять превью ко всем PDF-файлам в сообщениях. Если имя файла начинается с пробела, превью добавлено не будет, но при клике на ссылку PDF откроется в новой вкладке вместо скачивания.

    Все встроенные в браузеры PDF-просмотрщики имеют кнопку скачивания, так что вы сможете скачать файл оттуда, если захотите.

Спасибо за отладку и подробности @sharewoodsDavid. Оказалось, что теги <iframe> внутри тегов <a> не проходят валидацию.

Элемент iframe не должен быть потомком элемента a.

Поэтому ваше исправление абсолютно верно. Я внёс это изменение в PR выше.

Если вы хотите добавить элемент после другого элемента, вы можете использовать after() следующим образом:

someElement.after(newElement)

Если вы хотите добавить элемент перед другим элементом, вы можете использовать insertBefore() следующим образом:

// parentNode: родитель элемента, перед которым нужно вставить
// newNode: элемент, который нужно вставить
// referenceNode: элемент, перед которым нужно вставить

parentNode.insertBefore(newNode, referenceNode)

Нет. Никакие внешние сервисы здесь не задействованы. Вот как это работает.

  1. Пользователь посещает сообщение с вложением PDF.
  2. Браузер пользователя запрашивает вложение.
  3. Сервер отправляет его браузеру пользователя.
  4. Браузер пользователя открывает его с помощью встроенного PDF-просмотрщика.

Всё.

7 лайков

Отлично — спасибо @Johani. Подтверждаю, что работает в Chrome, FF и Safari. :+1:

3 лайка

Это здорово! Большое спасибо. Я установил и настроил! Именно то, что я искал.

5 лайков

Будет ли это работать ретроспективно для PDF-файлов, уже опубликованных на форуме?

2 лайка

Я только что протестировал это на своём тестовом сайте, и, похоже, это работает и для существующих, без необходимости «пересобирать HTML». :+1:

6 лайков

Я видел обновление в исходном коде на прошлой неделе, поэтому предполагаю, что этот компонент активен. Но, к сожалению, он никогда не работал у меня ни в одном браузере. Возможно, дело в настройке «медиа» в безопасном режиме? Только у меня не получается заставить это работать, или это распространённая проблема?

2 лайка

Мне тоже никогда не работало.

2 лайка

Компонент работает корректно. Какую проблему или ошибку вы наблюдаете?

3 лайка

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

Редактирование

Что ж, я проверил снова — в прошлый раз это было довольно давно.

DiscourseHub показывает это (iPad), и в логах Discourse нет ошибок:

Но когда я попробовал использовать Safari, он показал первую страницу, но не вторую.

1 лайк