Отлично! Спасибо @Johani. Могу подтвердить, что теперь это работает во всех трёх браузерах.
Отлично — это серьёзные улучшения, и для их достижения проделана огромная работа. Спасибо, что прислушались к нам, немного назойливым сообщникам из мира самохостинга!
Теперь компонент работает с загрузками в S3?
Я не пробовал, но это должно работать, если ваш бакет настроен правильно. Этот компонент отправляет запрос для загрузки PDF.
Такие запросы, выполняемые в JavaScript, блокируются, если источник не имеет права доступа к файлу. В результате возникает ошибка CORS. Если вы проверите консоль, то, скорее всего, увидите что-то вроде этого.

Сам компонент мало что может сделать в этой ситуации. Всё должно быть настроено в конфигурации вашего S3. Источник — ваш домен Discourse — должен иметь разрешение на выполнение таких запросов, чтобы избежать проблем с CORS.
Спасибо! Я вскоре снова решительно нырну в S3.
Ещё одно предложение: табуляция при наличии пробела перед именем файла
Я хочу, чтобы PDF по умолчанию отображался внутри страницы, а открывался в новой вкладке, если в имени файла есть пробел. Это даёт авторам возможность выбирать режим отображения (внутри страницы или во вкладке) для каждого PDF отдельно, а не для всего компонента.
Возможно, настройку компонента стоит изменить на «Какое поведение по умолчанию вы хотите?», и если в имени файла есть пробел, будет применяться альтернативный вариант.
Или, в качестве альтернативы, можно спросить, что должен делать пробел: отображать внутри страницы / открывать во вкладке / загружать файл.
Ааарг! Chrome снова показывает только серые квадраты. FF и Safari в порядке.
Отправляет ли этот компонент темы PDF-файл внешнему интерпретатору?
У меня включена функция «Защищенные медиа», так как я хочу избежать загрузки файлов внешним сервисом.
Я выяснил, что это происходит из-за следующего кода:
<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>
то всё заработает.
Но я не уверен, как исправить это в существующем коде.
@Johani
Ошибка связана со следующим кодом, строки 34–41:
const setUpPreviewType = (pdf) => {
if (previewMode === "Inline") {
const preview = createPreviewElement();
pdf.classList.add("pdf-attachment");
pdf.append(preview);
return preview;
}
Это решение, похоже, работает во всех браузерах.
pdf.parentNode.append(preview); вроде бы решает проблему (но в случае нескольких PDF-файлов превью отображаются под всеми ссылками, а не под каждой из них)
Но если родительский узел — это абзац, то это не должно быть проблемой, так как ссылка и iframe будут находиться внутри тега абзаца.
Чтобы обойти эту проблему, просто добавьте пустую строку между вложениями:
[doc1.pdf|attachment](...)
[doc2.pdf|attachment](...)
И с вашим решением предпросмотр PDF будет корректно отображаться и в Chrome.
Я только что внес несколько изменений.
Да, это имеет больше смысла, чем игнорирование файла. Вот как всё будет работать после обновления.
-
Если вы установите настройку в значение «Новая вкладка», компонент не будет добавлять превью в сообщениях. При клике на ссылку PDF откроется в новой вкладке.
-
Если вы установите настройку в значение «Встроенно», компонент будет по умолчанию добавлять превью ко всем PDF-файлам в сообщениях. Если имя файла начинается с пробела, превью добавлено не будет, но при клике на ссылку PDF откроется в новой вкладке вместо скачивания.
Все встроенные в браузеры PDF-просмотрщики имеют кнопку скачивания, так что вы сможете скачать файл оттуда, если захотите.
Спасибо за отладку и подробности @sharewoodsDavid. Оказалось, что теги <iframe> внутри тегов <a> не проходят валидацию.
Элемент
iframeне должен быть потомком элементаa.
Поэтому ваше исправление абсолютно верно. Я внёс это изменение в PR выше.
Если вы хотите добавить элемент после другого элемента, вы можете использовать after() следующим образом:
someElement.after(newElement)
Если вы хотите добавить элемент перед другим элементом, вы можете использовать insertBefore() следующим образом:
// parentNode: родитель элемента, перед которым нужно вставить
// newNode: элемент, который нужно вставить
// referenceNode: элемент, перед которым нужно вставить
parentNode.insertBefore(newNode, referenceNode)
Нет. Никакие внешние сервисы здесь не задействованы. Вот как это работает.
- Пользователь посещает сообщение с вложением PDF.
- Браузер пользователя запрашивает вложение.
- Сервер отправляет его браузеру пользователя.
- Браузер пользователя открывает его с помощью встроенного PDF-просмотрщика.
Всё.
Отлично — спасибо @Johani. Подтверждаю, что работает в Chrome, FF и Safari. ![]()
Это здорово! Большое спасибо. Я установил и настроил! Именно то, что я искал.
Будет ли это работать ретроспективно для PDF-файлов, уже опубликованных на форуме?
Я только что протестировал это на своём тестовом сайте, и, похоже, это работает и для существующих, без необходимости «пересобирать HTML». ![]()
Я видел обновление в исходном коде на прошлой неделе, поэтому предполагаю, что этот компонент активен. Но, к сожалению, он никогда не работал у меня ни в одном браузере. Возможно, дело в настройке «медиа» в безопасном режиме? Только у меня не получается заставить это работать, или это распространённая проблема?
Мне тоже никогда не работало.
Компонент работает корректно. Какую проблему или ошибку вы наблюдаете?
Я видел только обычную ссылку для скачивания файла. Я не стал углубляться в это, так как для меня это не было так важно — было бы неплохо иметь, но не более того. Так что извините, но я не могу осветить это подробнее.
Редактирование
Что ж, я проверил снова — в прошлый раз это было довольно давно.
DiscourseHub показывает это (iPad), и в логах Discourse нет ошибок:
Но когда я попробовал использовать Safari, он показал первую страницу, но не вторую.
