blob: 97394fd8f82799372e09262b5538309867a3f557 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# frozen_string_literal: true
module Banzai
module Filter
# HTML filter that inserts a node for each occurence of
# a given link format. To transform references to DB
# resources in place, prefer to inherit from AbstractReferenceFilter.
class InlineEmbedsFilter < HTML::Pipeline::Filter
# Find every relevant link, create a new node based on
# the link, and insert this node after any html content
# surrounding the link.
def call
return doc unless Feature.enabled?(:gfm_embedded_metrics, context[:project])
doc.xpath(xpath_search).each do |node|
next unless element = element_to_embed(node)
# We want this to follow any surrounding content. For example,
# if a link is inline in a paragraph.
node.parent.children.last.add_next_sibling(element)
end
doc
end
# Implement in child class.
#
# Return a Nokogiri::XML::Element to embed in the
# markdown.
def create_element(params)
end
# Implement in child class unless overriding #embed_params
#
# Returns the regex pattern used to filter
# to only matching urls.
def link_pattern
end
# Returns the xpath query string used to select nodes
# from the html document on which the embed is based.
#
# Override to select nodes other than links.
def xpath_search
'descendant-or-self::a[@href]'
end
# Creates a new element based on the parameters
# obtained from the target link
def element_to_embed(node)
return unless params = embed_params(node)
create_element(params)
end
# Returns a hash of named parameters based on the
# provided regex with string keys.
#
# Override to select nodes other than links.
def embed_params(node)
url = node['href']
link_pattern.match(url) { |m| m.named_captures }
end
end
end
end
|