diff options
Diffstat (limited to 'lib/banzai')
-rw-r--r-- | lib/banzai/filter/relative_link_filter.rb | 5 | ||||
-rw-r--r-- | lib/banzai/filter/video_link_filter.rb | 59 | ||||
-rw-r--r-- | lib/banzai/pipeline/gfm_pipeline.rb | 1 | ||||
-rw-r--r-- | lib/banzai/reference_extractor.rb | 9 |
4 files changed, 67 insertions, 7 deletions
diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/relative_link_filter.rb index c78da404607..337fb50317d 100644 --- a/lib/banzai/filter/relative_link_filter.rb +++ b/lib/banzai/filter/relative_link_filter.rb @@ -20,7 +20,7 @@ module Banzai process_link_attr el.attribute('href') end - doc.search('img').each do |el| + doc.css('img, video').each do |el| process_link_attr el.attribute('src') end @@ -112,8 +112,7 @@ module Banzai end def current_commit - @current_commit ||= context[:commit] || - ref ? repository.commit(ref) : repository.head_commit + @current_commit ||= context[:commit] || ref ? repository.commit(ref) : repository.head_commit end def relative_url_root diff --git a/lib/banzai/filter/video_link_filter.rb b/lib/banzai/filter/video_link_filter.rb new file mode 100644 index 00000000000..fd8b9a6f0cc --- /dev/null +++ b/lib/banzai/filter/video_link_filter.rb @@ -0,0 +1,59 @@ +module Banzai + module Filter + + # Find every image that isn't already wrapped in an `a` tag, and that has + # a `src` attribute ending with a video extension, add a new video node and + # a "Download" link in the case the video cannot be played. + class VideoLinkFilter < HTML::Pipeline::Filter + + def call + doc.xpath(query).each do |el| + el.replace(video_node(doc, el)) + end + + doc + end + + private + + def query + @query ||= begin + src_query = UploaderHelper::VIDEO_EXT.map do |ext| + "'.#{ext}' = substring(@src, string-length(@src) - #{ext.size})" + end + + "descendant-or-self::img[not(ancestor::a) and (#{src_query.join(' or ')})]" + end + end + + def video_node(doc, element) + container = doc.document.create_element( + 'div', + class: 'video-container' + ) + + video = doc.document.create_element( + 'video', + src: element['src'], + width: '400', + controls: true, + 'data-setup' => '{}') + + link = doc.document.create_element( + 'a', + element['title'] || element['alt'], + href: element['src'], + target: '_blank', + title: "Download '#{element['title'] || element['alt']}'") + download_paragraph = doc.document.create_element('p') + download_paragraph.children = link + + container.add_child(video) + container.add_child(download_paragraph) + + container + end + end + + end +end diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index b27ecf3c923..8d94b199c66 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -7,6 +7,7 @@ module Banzai Filter::SanitizationFilter, Filter::UploadLinkFilter, + Filter::VideoLinkFilter, Filter::ImageLinkFilter, Filter::EmojiFilter, Filter::TableOfContentsFilter, diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index bf366962aef..b26a41a1f3b 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -2,11 +2,11 @@ module Banzai # Extract possible GFM references from an arbitrary String for further processing. class ReferenceExtractor def initialize - @texts = [] + @texts_and_contexts = [] end def analyze(text, context = {}) - @texts << Renderer.render(text, context) + @texts_and_contexts << { text: text, context: context } end def references(type, project, current_user = nil) @@ -21,9 +21,10 @@ module Banzai def html_documents # This ensures that we don't memoize anything until we have a number of # text blobs to parse. - return [] if @texts.empty? + return [] if @texts_and_contexts.empty? - @html_documents ||= @texts.map { |html| Nokogiri::HTML.fragment(html) } + @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts) + .map { |html| Nokogiri::HTML.fragment(html) } end end end |