Проблемы с вставкой iframes через Ember API Discourse

Плагин вставляет i-frame в Discourse, и вы можете найти его здесь

Я стараюсь поддерживать его более или менее актуальным с последней версией, поэтому недавнее изменение, ломающее совместимость, стало неожиданностью. В данный момент мы используем версию 3.3.0.beta1-dev.

В консоли я получаю три сообщения об ошибках, которые выглядят так:

docuss.js:225 Uncaught (in promise) ReferenceError: Ember is not defined
at docuss.js:225:1

Скорее всего, объект Ember был удалён из API Discourse в недавней версии, поэтому эта ошибка возникает после обновления Discourse, затрагивающего эти объекты.

Вот все исправления, которые я внес:

Изменение 1

assets\javascripts\discourse\initializers\docuss.js.es6
строка 232

старый код:

const afterRender = res =>
  new Promise(resolve => {
    // @ts-ignore
    Ember.run.schedule('afterRender', null, () => resolve(res))

новый код:

import { schedule } from '@ember/runloop'

const afterRender = res =>
  new Promise(resolve => {
     schedule('afterRender', null, () => resolve(res))
  })

Изменение 2

assets\javascripts\discourse\lib\DcsIFrame.js.es6
строка 858

старый код:

  const afterRender = res =>
	new Promise(resolve => {
		Ember.run.schedule('afterRender', null, () => resolve(res))
	})

новый код:

	import { schedule } from '@ember/runloop'

	const afterRender = res =>
	  new Promise(resolve => {
		schedule('afterRender', null, () => resolve(res))
	  })

Изменение 3

assets\javascripts\discourse\lib\onDidTransition.js.es6
строка 239

старый код:

const afterRender = res =>
  new Promise(resolve => {
    Ember.run.schedule('afterRender', null, () => resolve(res))

новый код:

import { schedule } from '@ember/runloop'

const afterRender = res =>
  new Promise(resolve => {
      schedule('afterRender', null, () => resolve(res))

Это устранило все сообщения об ошибках в консоли, но породило серию новых:

 Discourse v3.3.0.beta1-dev — https://github.com/discourse/discourse/commits/4c7d58a883 — Ember v5.5.0
app.js:197 Uncaught ReferenceError: Ember is not defined
    at s.callback (docuss.js:210:1)
    at s.exports (loader.js:106:1)
    at requireModule (loader.js:27:1)
    at y (app.js:171:18)
    at w (app.js:194:19)
    at app.js:157:29
    at e.start (app.js:51:5)
    at HTMLDocument.<anonymous> (start-app.js:5:7)
    at discourse-boot.js:20:12
    at discourse-boot.js:1:1

Вот рабочая платформа с включённым плагином, на случай если это поможет

Встречался ли кому-нибудь подобный вопрос? Кто-нибудь сталкивался с проблемами из-за изменений в объектах API Ember? Любые предложения по их исправлению будут очень кстати.

Привет!

Вы забыли это:

Думаю, можно сделать что-то вроде этого. Это всё ещё должно работать.

import { observes } from "discourse-common/utils/decorators";

@observes("model.tags")
tagsChanged() {

}

Кстати, контроллер композера теперь перемещён в сервис.

Вы уже посмотрели рекомендуемую альтернативу на странице GitHub?

Полагаю, автор активен здесь.

Спасибо за предложение @Heliosurge. Однако мы глубоко интегрировали старую версию в наш проект, поэтому с благословения авторов мы взяли на себя её поддержку.

В данный момент в нашем сообществе с открытым исходным кодом немного не хватает разработчиков с соответствующими навыками.

Да, это вполне логично.

Спасибо, @Arkshine. Мой ноутбук вышел из строя, когда сменный зарядный кабель повредил цепь зарядки, поэтому я не мог протестировать это, пока вчера не починил ноутбук.

Я поместил оператор импорта в начало страницы, а ваш код — под ним, но при попытке добавить его или похожие варианты сталкиваюсь с ошибками синтаксиса:

Visual Studio находит следующие ошибки:

// Новая функция tagsChanged с декоратором @observes
@observes("model.tags")
tagsChanged() {
  // Проверка, является ли это баллонным тегом

Открывающая скобка в конце этой строки: tagsChanged() {

сопровождается сообщением об ошибке:
‘;’ expected.ts(1005)

  1. Закрывающая скобка в конце кода также помечена ошибкой с сообщением:

‘}’ expected.ts(1005)
docuss.js.es6(219, 54): Парсер ожидал найти ‘}’, чтобы соответствовать символу ‘{’ здесь.

Это строка 219:
tagsChanged: Ember.observer('model.tags', function() {

Мой сервер выводит следующее при попытке сборки:

  251 |     }, 0);
  252 |   }
> 253 | }.observes("model.tags"),
      |                          ^
        в /tmp/broccoli-6523ExbXtskE5c0h/out-1067-funnel
        в Babel (Babel: discourse-plugins)
  - имя: Error
  - аннотация узла: Babel: discourse-plugins
  - имя узла: Babel
  - исходное сообщение об ошибке: /var/www/discourse/app/assets/javascripts/discourse/discourse/plugins/docuss/discourse/initializers/docuss.js: Unexpected token (253:25)

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

Теперь, оглядываясь назад, не вижу, что вызывает проблему. Я откатил всё к исходному варианту. Не мог бы кто-нибудь подсказать, что нужно изменить здесь, чтобы обновить код под новый API Ember?

Вот несколько рекомендаций:

  • Настройки сайта перенесены в сервис:

    const siteSettings = container.lookup('service:site-settings');
    if (!siteSettings.docuss_enabled) {
      return;
    }
    
  • location:discourse-locationlocation:history

  • afterRender().then(() => onAfterRender(container));
    afterRender — это декоратор, который размещается над методом в классе компонента; использовать его напрямую как функцию не следует.
    Думаю, вам нужно (хотя, возможно, это и не требуется) следующее:

    import { schedule } from '@ember/runloop';
    schedule("afterRender", () => onAfterRender(container))
    
  • У вас есть большой фрагмент кода вне функции composeStateChanged, судя по всему.
    Также здесь можно использовать сервис маршрутизатора: container.lookup('router:main').transitionTo(path);this.router.transitionTo(path);

  • Заголовок был модернизирован. Кастомизация виджета home-logo в вашем контексте устарела. Дополнительную информацию см. здесь: Upcoming Header Changes - Preparing Themes and Plugins.
    В вашем случае необходимо установить настройку glimmer header mode в значение auto или enabled. Затем вы можете использовать выходной порт плагина для замены содержимого:

    api.renderInOutlet("home-logo-contents", <template>
      <HomeLogoContents
        @logoSmallUrl={{container.dcsHeaderLogo._smallLogoUrl}}
        @logoUrl={{container.dcsHeaderLogo._logoUrl}}
        @minimized={{@outletArgs.minimized}}
        @mobileLogoUrl={{container.dcsHeaderLogo._mobileLogoUrl}}
        @showMobileLogo={{@outletArgs.showMobileLogo}}
        @title={{@outletArgs.title}}
      />
    </template>);
    

    Примечание: чтобы использовать синтаксис glimmer <template>, убедитесь, что расширение файла изменено на .gjs.
    Также можно использовать этот способ:

     api.registerValueTransformer("home-logo-image-url", (transformer) => {
        let url = transformer.value;
        if (transformer.context.name === 'logo') {
          url = container.dcsHeaderLogo._logoUrl;
        } else if (transformer.context.name === 'logo_small') {
          url = container.dcsHeaderLogo._smallLogoUrl;
        } else if (transformer.context.name === 'logo_mobile') {
          url = container.dcsHeaderLogo._mobileLogoUrl;
        }
        return url;
      });
    

    Для изменения URL:

    api.registerValueTransformer("home-logo-href", () => container.dcsHeaderLogo._href);
    

    Примечание: Я полагаю, что код для перерисовки в setLogo не будет работать с glimmer-компонентом.

    Примечание после тестирования: Однако ни одно из решений не сработает, так как заголовок рендерится до того, как вы сможете получить логотипы из JSON. У меня пока нет готового решения для этого. Не уверен, есть ли лучший способ: я бы перенес загрузку JSON в сервис и отслеживал результат. Затем используйте выходной порт плагина, описанный выше, с glimmer-компонентом. Таким образом, на основе переменной отслеживания вы сможете автоматически инициировать обновление компонента.

С этим всё вроде как работает. Пока ещё есть неработающие части, например композер. Я не углублялся в это слишком сильно. По крайней мере, больше нет блокирующей ошибки. :slightly_smiling_face:

Надеюсь, это поможет.

Это действительно полезно, спасибо :slight_smile: