Как получить HTML, возвращаемый jquery-oembed-all, в виде строки?

Я тестирую jquery-oembed-all в качестве решения для еще один вопрос, который я задал. Сценарий представляет собой небольшой файл javascript, загружаемый на страницу и предоставляющий функцию oembed для извлечения кода встраивания мультимедиа.

Я легко получаю iframe oEmbed по ссылке, например:

<script>
  $(function(){
    tag = $(document.createElement('div')).oembed('https://vimeo.com/40179668');
    $('.header').append(tag);
  });
</script>

Это отлично работает и добавляет сгенерированный oEmbed элемент iframe к .header на странице. Однако мне нужен сгенерированный HTML в виде строки. Поиск в tag[0].outerHTML и даже tag[0].parent()[0].outerHTML только что показал, что tag является исходным пустым div, созданным в сценарии, но в нем явно есть весь код для встраивания, потому что встроенное видео загружается на страницу.

Как получить HTML, возвращаемый функцией oembed, в виде текстовой строки? Нужно ли мне проходить DOM из созданного тега div, чтобы найти его?

EDIT: я добавил несколько предупреждений, и все они связаны со временем. Поскольку это сетевой вызов, функция oEmbed не вернула блок HTML к тому времени, когда я запрашиваю файл outerHTML.

РЕДАКТИРОВАТЬ 2: Похоже, это можно решить с помощью обратных вызовов JS, поскольку вызов oEmbed является асинхронным. Когда у меня будет время искать решение, я опубликую его здесь как ответ.


person Dan Weaver    schedule 06.11.2013    source источник
comment
Вы случайно не нашли решение этой проблемы?   -  person Natetronn    schedule 07.12.2013
comment
@Natetronn Я добавил свое решение ниже. Сейчас это довольно хакерски, но это работает. Я буду реорганизовать это в ближайшее время и опубликовать обратно. Также предполагается, что вы делаете это в приложении Rails.   -  person Dan Weaver    schedule 08.12.2013


Ответы (1)


РЕШЕНИЕ:

Поскольку это приложение на Rails, я решил использовать гем oembed и анализировать ссылки на видео, когда текст отображается, а не при вводе. Это лучшее решение для меня, так как хранение голых URL-адресов видео более перспективно, чем хранение полного кода iframe для встраивания, возвращаемого oembed, в надежде, что он никогда не изменится.

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

При отображении урока я запускаю parse_media_embeds на lesson.notes, который находит все ссылки и для любых соответствующих медиа-сайтов извлекает код oEmbed (с rescue для ошибок) и заменяет ссылку iframe. Совершенно дерганый, но это позволило мне продолжить работу с приложением.

Я опубликую новый код, когда рефакторинг его.

ПРОСМОТР: урок.html.rb

...
<section class='lesson-notes'>
  <p><%= lesson.parse_media_embeds.html_safe %></p>
</section>
...

МОДЕЛЬ: урок.rb

def parse_media_embeds
  # get an array of links in the notes
  links = URI.extract self.notes, /http(s)?/
  # due to wysihtml5 parsing each link is stored twice, once as url and once as text
  # like <a href='http://google.com'>http://google.com</a>
  # so remove the double references
  for pos in (0..links.count)
    link.delete_at(pos)
  end
  # now replace each link that matches the Regexp pattern with oembed version
  links.each do |link|
    # only replace links for YouTube, Vimeo and Soundcloud
    if link.match(/youtu\.be|youtube|vimeo|soundcloud/)
      # get the full link tag, which includes both instances of the link text
      string = /(<a\w*[^>]*>#{Regexp.escape(link)}[^<]*<\/a>)/
      embed = get_oembed(link)
      self.notes = self.notes.gsub(string, embed) if embed
    end
  end
  self.notes
end

МОДЕЛЬ: урок.rb

def get_oembed(link)
  # each provider has a different set of params
  if link.match(/youtu\.be|youtube/)
    begin
      resource = OEmbed::Providers::Youtube.get(link, {maxwidth: 320})
    rescue
      return
    end
    resource.html
  elsif link.match(/vimeo/)
    begin
      resource = OEmbed::Providers::Vimeo.get(link, {maxwidth: 320})
    rescue
      return
    end
    resource.html
  elsif link.match(/soundcloud/)
    begin
      resource = OEmbed::Providers::SoundCloud.get(link, {color: '39d', show_comments: false})
    rescue
      return
    end
    resource.html
  else
    return
  end
end
person Dan Weaver    schedule 07.12.2013