embeddable_content 0.4.0.beta7 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/README.md +2 -2
- data/app/assets/javascripts/geogebra/support.js +0 -1
- data/app/services/embeddable_content/doc_processor.rb +3 -10
- data/app/services/embeddable_content/embedder.rb +1 -1
- data/app/services/embeddable_content/images/doc_processor.rb +28 -6
- data/app/services/embeddable_content/images/img_tag_attributes.rb +2 -2
- data/app/services/embeddable_content/images/modal_dialog.rb +2 -2
- data/app/services/embeddable_content/images/node_processor.rb +1 -1
- data/app/services/embeddable_content/presentation_tags/node_processor.rb +1 -29
- data/app/services/embeddable_content/record_node_processor.rb +2 -2
- data/app/services/embeddable_content/tex/base_renderer.rb +89 -31
- data/app/services/embeddable_content/tex/canvas_renderer.rb +4 -36
- data/app/services/embeddable_content/tex/doc_processor.rb +34 -11
- data/app/services/embeddable_content/tex/mathjax_renderer.rb +2 -8
- data/app/services/embeddable_content/tex/mml_renderer.rb +4 -17
- data/app/services/embeddable_content/tex/schoology_string_renderer.rb +15 -0
- data/app/services/embeddable_content/tex/svg_renderer.rb +4 -12
- data/app/services/embeddable_content/video_links/doc_processor.rb +1 -13
- data/app/services/mathjax/api/client.rb +7 -0
- data/app/views/embeddable_content/replacements/images/_modal_content.html.slim +2 -2
- data/app/views/embeddable_content/replacements/video_links/_video_embed.html.slim +1 -1
- data/embeddable_content-1.0.0.gem +0 -0
- data/lib/embeddable_content/engine.rb +0 -2
- data/lib/embeddable_content/version.rb +1 -1
- metadata +10 -9
- data/app/services/embeddable_content/has_moveable_nodes.rb +0 -69
- data/app/services/embeddable_content/tex/uri_encode_component.rb +0 -175
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a74872d75d69fe856b679579a53da713e24d3fe17c0b70cecc5d701311cce6
|
4
|
+
data.tar.gz: 607ba9f7470597a6f9fae3d5c93ced5135b6f52497e6f137fc7b99ce45814e9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bda46ef7f616afca38e551c63c6715b9eebfbe3958bb79b2978e2f19522c9176a5ffdcab31b491489224abc870687120f6de2839be4a84f905573ef7a71ab0e
|
7
|
+
data.tar.gz: ca7fb19df68cdf847c9a7323fb82074c4e7a7c9ebf8bafc0c87895d85bd496fc2cd4196ae833a04bbfca2d02a13c3ae680a19547bd10d5b9e2034f5461e0a3c7
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -70,6 +70,6 @@ $ gem push embeddable_content-0.2.0.gem
|
|
70
70
|
|
71
71
|
| Version | Changes |
|
72
72
|
| --- | --- |
|
73
|
-
| 0.
|
73
|
+
| 1.0.1 | Major version corresponds to upgrading CMS to Rails 7. IIAB should continue using 0.x.x releases for now. |
|
74
74
|
| 0.3.1 | Meaningless change as I (EDC) experiment with gem host. |
|
75
|
-
| 0.2.0 | NIMAS export now using embedder for TeX. However, the embedder is not yet using the full TexExprssions
|
75
|
+
| 0.2.0 | NIMAS export now using embedder for TeX. However, the embedder is not yet using the full TexExprssions table. |
|
@@ -9,6 +9,5 @@ function loadGeogebraApplet(elmt) {
|
|
9
9
|
dataNode = elmt.getElementsByClassName('ggb-base-64-data')[0],
|
10
10
|
parameters = JSON.parse(dataNode.dataset['parameters']),
|
11
11
|
applet = new GGBApplet(parameters, '5.0');
|
12
|
-
applet.setHTML5Codebase('/GeoGebra/HTML5/5.0/web3d/');
|
13
12
|
applet.inject(container.id);
|
14
13
|
};
|
@@ -1,8 +1,7 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
class DocProcessor < EmbedderBase
|
3
|
-
include HasMoveableNodes
|
4
|
-
|
5
3
|
PROCESS_NODES_BY_DEFAULT = true
|
4
|
+
|
6
5
|
attr_reader :embedder
|
7
6
|
|
8
7
|
delegate :document, :html, :rebuild_document, to: :embedder
|
@@ -29,16 +28,10 @@ module EmbeddableContent
|
|
29
28
|
private
|
30
29
|
|
31
30
|
def refresh_html
|
32
|
-
html.replace document.
|
31
|
+
html.replace document.to_s
|
33
32
|
end
|
34
33
|
|
35
|
-
def pre_process
|
36
|
-
update_moveable_nodes if update_moveable_nodes?
|
37
|
-
end
|
38
|
-
|
39
|
-
def update_moveable_nodes?
|
40
|
-
false
|
41
|
-
end
|
34
|
+
def pre_process; end
|
42
35
|
|
43
36
|
def process_matching_nodes
|
44
37
|
matching_nodes.each.with_index(1) { |node, idx| process_node(node, idx) }
|
@@ -5,14 +5,12 @@ module EmbeddableContent
|
|
5
5
|
class DocProcessor < EmbeddableContent::DocProcessor
|
6
6
|
delegate :image_catalog, to: :embedder
|
7
7
|
|
8
|
-
|
8
|
+
CLASS_IMG_TAG_RELOCATED = 'img-tag-relocated-by-embedder'
|
9
9
|
|
10
|
-
|
11
|
-
true
|
12
|
-
end
|
10
|
+
private
|
13
11
|
|
14
|
-
def
|
15
|
-
|
12
|
+
def pre_process
|
13
|
+
move_img_tags_out_from_p_tags
|
16
14
|
end
|
17
15
|
|
18
16
|
def post_process
|
@@ -27,6 +25,30 @@ module EmbeddableContent
|
|
27
25
|
def node_selector
|
28
26
|
'img'
|
29
27
|
end
|
28
|
+
|
29
|
+
def move_img_tags_out_from_p_tags
|
30
|
+
img_tags_inside_p_tags.each do |img_tag|
|
31
|
+
move_img_tag_out_from_p_tag img_tag
|
32
|
+
end
|
33
|
+
remove_affected_empty_p_tags
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_affected_empty_p_tags
|
37
|
+
document.css("p.#{CLASS_IMG_TAG_RELOCATED}").each do |p_tag|
|
38
|
+
remove_if_empty p_tag
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def move_img_tag_out_from_p_tag(img_tag)
|
43
|
+
img_tag.parent.tap do |p_tag|
|
44
|
+
p_tag.add_previous_sibling img_tag
|
45
|
+
p_tag.add_class CLASS_IMG_TAG_RELOCATED
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def img_tags_inside_p_tags
|
50
|
+
@img_tags_inside_p_tags ||= document.css 'p > img'
|
51
|
+
end
|
30
52
|
end
|
31
53
|
end
|
32
54
|
end
|
@@ -5,7 +5,7 @@ module EmbeddableContent
|
|
5
5
|
attr_reader :node_processor
|
6
6
|
|
7
7
|
delegate :alt_text, :attached_file, :record, :aria_attrs?,
|
8
|
-
:cms_url, :s3_url, :
|
8
|
+
:cms_url, :s3_url, :s3_ttl_url, :target,
|
9
9
|
:node, to: :node_processor
|
10
10
|
delegate :image, to: :record
|
11
11
|
delegate :raw_svg, to: :image_downloader
|
@@ -28,7 +28,7 @@ module EmbeddableContent
|
|
28
28
|
when :cms then cms_url
|
29
29
|
when :editable then downloaded_file_url
|
30
30
|
when :exported, :qti then s3_url with_extension: false
|
31
|
-
when :print, :web then
|
31
|
+
when :print, :web then s3_ttl_url
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -5,7 +5,7 @@ module EmbeddableContent
|
|
5
5
|
|
6
6
|
attr_reader :node_processor
|
7
7
|
|
8
|
-
delegate :record_css_id_for, :
|
8
|
+
delegate :record_css_id_for, :s3_ttl_url, :caption, :attribution,
|
9
9
|
:alt_text, to: :node_processor
|
10
10
|
|
11
11
|
def initialize(node_processor)
|
@@ -13,7 +13,7 @@ module EmbeddableContent
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def img_tag_attrs
|
16
|
-
{ src:
|
16
|
+
{ src: s3_ttl_url,
|
17
17
|
width: '80%',
|
18
18
|
alt: strip_tags(alt_text),
|
19
19
|
role: :image }
|
@@ -15,35 +15,7 @@ module EmbeddableContent
|
|
15
15
|
delegate :template_based?, to: :presentation_tag
|
16
16
|
|
17
17
|
def replace_node
|
18
|
-
template_based? ?
|
19
|
-
end
|
20
|
-
|
21
|
-
def place_node
|
22
|
-
if node_in_p_tag?
|
23
|
-
add_empty_p_tag_for_pre_mjpage_compatibility
|
24
|
-
place_node_after_parent_node
|
25
|
-
else
|
26
|
-
place_node_within_parent_node
|
27
|
-
end
|
28
|
-
remove_node
|
29
|
-
true
|
30
|
-
end
|
31
|
-
|
32
|
-
def place_node_after_parent_node
|
33
|
-
parent_node.add_next_sibling replacement_node
|
34
|
-
end
|
35
|
-
|
36
|
-
def place_node_within_parent_node
|
37
|
-
parent_node << replacement_node
|
38
|
-
end
|
39
|
-
|
40
|
-
def add_empty_p_tag_for_pre_mjpage_compatibility
|
41
|
-
parent_node
|
42
|
-
.add_next_sibling '<p class="empty-p-tag-added-for-pre-mjpage-compatability"></p>'
|
43
|
-
end
|
44
|
-
|
45
|
-
def node_in_p_tag?
|
46
|
-
parent_node&.name == 'p'
|
18
|
+
template_based? ? super : modify_parent
|
47
19
|
end
|
48
20
|
|
49
21
|
def modify_parent
|
@@ -27,13 +27,13 @@ module EmbeddableContent
|
|
27
27
|
src_url
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def s3_ttl_url
|
31
31
|
if Rails.env.test?
|
32
32
|
Pathname
|
33
33
|
.new(ActiveStorage::Blob.service.send(:path_for, blob.key))
|
34
34
|
.relative_path_from Rails.root
|
35
35
|
else
|
36
|
-
blob.
|
36
|
+
blob.url(content_type: content_type)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -1,66 +1,124 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module EmbeddableContent
|
2
4
|
module Tex
|
5
|
+
class RenderError < StandardError
|
6
|
+
attr_reader :script, :stderr, :status
|
7
|
+
|
8
|
+
def initialize(script, stderr, status, api_errors)
|
9
|
+
@script = script
|
10
|
+
@stderr = stderr
|
11
|
+
@status = status
|
12
|
+
super "Unable to resolve error raised calling #{script}: #{status}\n#{stderr}\n#{api_errors}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
3
16
|
class BaseRenderer
|
4
|
-
|
17
|
+
RENDER_TEX_JS_PATH = Pathname.new('lib').join 'tasks/render_tex.js'
|
5
18
|
|
6
|
-
|
7
|
-
to: :tex_expression
|
19
|
+
attr_reader :html, :stdout, :stderr, :status
|
8
20
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@document = document
|
21
|
+
def initialize(html)
|
22
|
+
@html = html
|
12
23
|
end
|
13
24
|
|
14
25
|
def render
|
15
|
-
|
26
|
+
return html unless rendering_required?
|
27
|
+
|
28
|
+
run_script
|
16
29
|
end
|
17
30
|
|
18
31
|
private
|
19
32
|
|
20
|
-
def
|
21
|
-
|
33
|
+
def rendering_required?
|
34
|
+
not_yet_rendered? && target_format.present?
|
22
35
|
end
|
23
36
|
|
24
|
-
def
|
25
|
-
|
37
|
+
def not_yet_rendered?
|
38
|
+
status.blank?
|
26
39
|
end
|
27
40
|
|
28
|
-
def
|
29
|
-
|
41
|
+
def render_failed?
|
42
|
+
failed_status || stderr.present?
|
30
43
|
end
|
31
44
|
|
32
|
-
def
|
33
|
-
|
45
|
+
def failed_status
|
46
|
+
status.present? && !status.success?
|
34
47
|
end
|
35
48
|
|
36
|
-
def
|
37
|
-
@
|
38
|
-
|
39
|
-
|
49
|
+
def render_error
|
50
|
+
@render_error ||= RenderError.new script, stderr, status, api_errors
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_script
|
54
|
+
@run_script ||= Open3.capture3(script, stdin_data: html).tap do |stdout, stderr, status|
|
55
|
+
@stdout = stdout
|
56
|
+
@stderr = stderr
|
57
|
+
@status = status
|
40
58
|
end
|
59
|
+
render_failed? ? try_api_client : html.replace(stdout)
|
60
|
+
end
|
61
|
+
|
62
|
+
def script
|
63
|
+
@script ||= [RENDER_TEX_JS_PATH, '--output', target_format].join(' ')
|
64
|
+
end
|
65
|
+
|
66
|
+
REGEX_TEX_STRING = /Formula\s+(?<texstring>.*)\s+contains the following errors:/.freeze
|
67
|
+
def offending_tex_string
|
68
|
+
@offending_tex_string ||= REGEX_TEX_STRING.match(stderr)[:texstring].strip if
|
69
|
+
stderr.present?
|
41
70
|
end
|
42
71
|
|
43
|
-
def
|
44
|
-
Nokogiri::
|
72
|
+
def document
|
73
|
+
@document ||= Nokogiri::HTML html
|
45
74
|
end
|
46
75
|
|
47
|
-
def
|
48
|
-
''
|
76
|
+
def all_spans
|
77
|
+
@all_spans ||= document.css 'span'
|
49
78
|
end
|
50
79
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
80
|
+
def api_errors
|
81
|
+
offending_node.blank? ? '' : api_client.errors.unshift('API errors:').join("\n")
|
82
|
+
end
|
83
|
+
|
84
|
+
def try_api_client
|
85
|
+
raise render_error if offending_node.blank?
|
86
|
+
raise render_error unless api_client.success?
|
87
|
+
|
88
|
+
offending_node.content = ''
|
89
|
+
offending_node.add_child repaired_content
|
90
|
+
renderer_for_repaired_document.render
|
91
|
+
end
|
92
|
+
|
93
|
+
def renderer_for_repaired_document
|
94
|
+
@renderer_for_repaired_document ||=
|
95
|
+
self.class.new html.replace(document.to_html)
|
96
|
+
end
|
97
|
+
|
98
|
+
def repaired_span
|
99
|
+
@repaired_span = %w[<span class="mathjax-api"></span>].tap do |span|
|
100
|
+
span << repaired_content
|
55
101
|
end
|
56
102
|
end
|
57
103
|
|
58
|
-
def
|
59
|
-
|
104
|
+
def repaired_content
|
105
|
+
@repaired_content ||= api_client.send target_format
|
106
|
+
end
|
107
|
+
|
108
|
+
def api_client
|
109
|
+
@api_client ||= Mathjax::Api::Client.new offending_tex_string
|
60
110
|
end
|
61
111
|
|
62
|
-
def
|
63
|
-
@
|
112
|
+
def offending_node
|
113
|
+
@offending_node ||=
|
114
|
+
all_spans.detect { |node| offending_tex_appears_in?(node) }
|
115
|
+
end
|
116
|
+
|
117
|
+
REGEX_NODE_TEX_CONTENT = /\\\(\s*(?<tex_string>.*)\s*\\\)/m.freeze
|
118
|
+
def offending_tex_appears_in?(node)
|
119
|
+
node.content.match(REGEX_NODE_TEX_CONTENT).then do |md|
|
120
|
+
md.present? && md[:tex_string]&.strip.eql?(offending_tex_string)
|
121
|
+
end
|
64
122
|
end
|
65
123
|
end
|
66
124
|
end
|
@@ -1,46 +1,14 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module EmbeddableContent
|
2
4
|
module Tex
|
3
5
|
class CanvasRenderer < BaseRenderer
|
4
|
-
require 'embeddable_content/tex/uri_encode_component'
|
5
|
-
|
6
6
|
def target_format
|
7
7
|
:canvas
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
#################################################
|
13
|
-
def math_node
|
14
|
-
@math_node ||= Nokogiri::XML::Node.new('img', document).tap do |node|
|
15
|
-
node['class'] = 'equation_image'
|
16
|
-
node['title'] = unadorned_tex_string
|
17
|
-
node['src'] = expression_uri
|
18
|
-
node['alt'] = alt_expression
|
19
|
-
node['data-equation-content'] = unadorned_tex_string
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def rendered_node
|
24
|
-
@rendered_node ||= emptied_math_span.then { |span| span << math_node }
|
25
|
-
end
|
26
|
-
|
27
|
-
def base_replacement_span
|
28
|
-
@base_replacement_span ||= blank_span.tap do |span|
|
29
|
-
span['class'] = 'math'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def alt_expression
|
34
|
-
@alt_expression ||= "LaTeX: #{unadorned_tex_string}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def expression_uri
|
38
|
-
@expression_uri ||= "/equation_images/#{doubly_encoded_expression}"
|
39
|
-
end
|
40
|
-
|
41
|
-
def doubly_encoded_expression
|
42
|
-
@doubly_encoded_expression ||=
|
43
|
-
encodeURIComponent encodeURIComponent unadorned_tex_string
|
10
|
+
def render
|
11
|
+
html.replace Mathjax::CanvasRenderer.new(html).render
|
44
12
|
end
|
45
13
|
end
|
46
14
|
end
|
@@ -1,31 +1,54 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
module Tex
|
3
3
|
class DocProcessor < EmbeddableContent::DocProcessor
|
4
|
-
|
5
|
-
|
4
|
+
REPAIRED_MATH_CSS_CLASS = 'math-repaired'.freeze
|
5
|
+
REPAIRED_MATH_CSS_SELECTOR = ".#{REPAIRED_MATH_CSS_CLASS}".freeze
|
6
|
+
|
7
|
+
delegate :remove_repaired_math_spans?, to: :embedder
|
6
8
|
|
7
9
|
private
|
8
10
|
|
11
|
+
def process_nodes?
|
12
|
+
remove_repaired_math_spans?
|
13
|
+
end
|
14
|
+
|
9
15
|
def process_node(node, _node_index)
|
10
|
-
|
16
|
+
remove_repaired_math_span node
|
11
17
|
end
|
12
18
|
|
13
|
-
# TODO: resolve this --- still needed?
|
14
19
|
def remove_repaired_math_span(node)
|
15
|
-
|
20
|
+
node.replace node.content
|
21
|
+
end
|
22
|
+
|
23
|
+
def post_process
|
24
|
+
refresh_html
|
25
|
+
render_tex
|
26
|
+
fix_mml_fragments if fix_mml_fragments?
|
27
|
+
rebuild_document
|
16
28
|
end
|
17
29
|
|
18
30
|
def node_selector
|
19
|
-
|
31
|
+
REPAIRED_MATH_CSS_SELECTOR
|
32
|
+
end
|
33
|
+
|
34
|
+
def repaired_math_nodes
|
35
|
+
@repaired_math_nodes ||= document.css(REPAIRED_MATH_CSS_SELECTOR)
|
36
|
+
end
|
37
|
+
|
38
|
+
def render_tex
|
39
|
+
tex_renderer.new(html).render
|
40
|
+
end
|
41
|
+
|
42
|
+
def fix_mml_fragments?
|
43
|
+
embedder.fragment? && embedder.xml?
|
20
44
|
end
|
21
45
|
|
22
|
-
def
|
23
|
-
|
46
|
+
def fix_mml_fragments
|
47
|
+
html.replace Nokogiri::HTML(html).at('body').children.to_xml
|
24
48
|
end
|
25
49
|
|
26
|
-
def
|
27
|
-
|
28
|
-
"#{module_name}::#{tex_output_format.classify}Renderer".constantize
|
50
|
+
def tex_renderer
|
51
|
+
"#{module_name}::#{tex_output_format.classify}Renderer".constantize
|
29
52
|
end
|
30
53
|
end
|
31
54
|
end
|
@@ -1,23 +1,10 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module EmbeddableContent
|
2
4
|
module Tex
|
3
5
|
class MmlRenderer < BaseRenderer
|
4
|
-
|
5
|
-
|
6
|
-
# TODO: update this once embedder specs working
|
7
|
-
def replacement_css_classes
|
8
|
-
@replacement_css_classes ||=
|
9
|
-
displaystyle? ? 'mjpage mjpage__block' : 'mjpage'
|
10
|
-
end
|
11
|
-
|
12
|
-
def math_content
|
13
|
-
mml
|
14
|
-
end
|
15
|
-
|
16
|
-
def math_node
|
17
|
-
super.tap do |node|
|
18
|
-
node['display'] = 'block' if displaystyle?
|
19
|
-
node['alttext'] = unadorned_tex_string
|
20
|
-
end
|
6
|
+
def target_format
|
7
|
+
:mml
|
21
8
|
end
|
22
9
|
end
|
23
10
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module EmbeddableContent
|
4
|
+
module Tex
|
5
|
+
class SchoologyStringRenderer < BaseRenderer
|
6
|
+
def target_format
|
7
|
+
:schoology_string
|
8
|
+
end
|
9
|
+
|
10
|
+
def render_format(_format)
|
11
|
+
Mathjax::SchoologyStringRenderer.new(html).render
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,18 +1,10 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module EmbeddableContent
|
2
4
|
module Tex
|
3
5
|
class SvgRenderer < BaseRenderer
|
4
|
-
|
5
|
-
|
6
|
-
def rendered_node
|
7
|
-
@rendered_node ||= emptied_math_span.then { |span| span << math_node }
|
8
|
-
end
|
9
|
-
|
10
|
-
def math_content
|
11
|
-
svg
|
12
|
-
end
|
13
|
-
|
14
|
-
def base_replacement_span
|
15
|
-
emptied_math_span
|
6
|
+
def target_format
|
7
|
+
:svg
|
16
8
|
end
|
17
9
|
end
|
18
10
|
end
|
@@ -1,17 +1,5 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
module VideoLinks
|
3
|
-
class DocProcessor < EmbeddableContent::DocProcessor
|
4
|
-
TARGETS_FOR_WHICH_NODES_ARE_UNMOVEABLE = %i[cms exported kiddom web].freeze
|
5
|
-
|
6
|
-
def update_moveable_nodes?
|
7
|
-
TARGETS_FOR_WHICH_NODES_ARE_UNMOVEABLE.exclude? target
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def relocate_moveable_node(moveable_node)
|
13
|
-
place_moveable_node_after_parent moveable_node
|
14
|
-
end
|
15
|
-
end
|
3
|
+
class DocProcessor < EmbeddableContent::DocProcessor; end
|
16
4
|
end
|
17
5
|
end
|
@@ -15,7 +15,7 @@ div.im-c-modal__content.im-c-content
|
|
15
15
|
- if description.present?
|
16
16
|
p
|
17
17
|
strong> Description:
|
18
|
-
|
18
|
+
= description
|
19
19
|
img *img_tag_attrs
|
20
20
|
- if caption.present?
|
21
21
|
p id = caption_id
|
@@ -24,7 +24,7 @@ div.im-c-modal__content.im-c-content
|
|
24
24
|
- if attribution.present?
|
25
25
|
p id = attribution_id
|
26
26
|
strong> Attribution:
|
27
|
-
|
27
|
+
=> modal_dialog.attribution_display_text
|
28
28
|
a href = attribution.original_url
|
29
29
|
| Source
|
30
30
|
| .
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embeddable_content
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Connally
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -175,7 +175,6 @@ files:
|
|
175
175
|
- app/services/embeddable_content/fragment_embedder.rb
|
176
176
|
- app/services/embeddable_content/geogebra_files/doc_processor.rb
|
177
177
|
- app/services/embeddable_content/geogebra_files/node_processor.rb
|
178
|
-
- app/services/embeddable_content/has_moveable_nodes.rb
|
179
178
|
- app/services/embeddable_content/html_tags/doc_processor.rb
|
180
179
|
- app/services/embeddable_content/html_tags/node_processor.rb
|
181
180
|
- app/services/embeddable_content/images/attributions_processor.rb
|
@@ -199,8 +198,8 @@ files:
|
|
199
198
|
- app/services/embeddable_content/tex/doc_processor.rb
|
200
199
|
- app/services/embeddable_content/tex/mathjax_renderer.rb
|
201
200
|
- app/services/embeddable_content/tex/mml_renderer.rb
|
201
|
+
- app/services/embeddable_content/tex/schoology_string_renderer.rb
|
202
202
|
- app/services/embeddable_content/tex/svg_renderer.rb
|
203
|
-
- app/services/embeddable_content/tex/uri_encode_component.rb
|
204
203
|
- app/services/embeddable_content/token_replacement_map.rb
|
205
204
|
- app/services/embeddable_content/tree_based_node_processor.rb
|
206
205
|
- app/services/embeddable_content/video_links/doc_processor.rb
|
@@ -209,6 +208,7 @@ files:
|
|
209
208
|
- app/services/embeddable_content/visual_element_node_processor.rb
|
210
209
|
- app/services/embeddable_content/widget_files/doc_processor.rb
|
211
210
|
- app/services/embeddable_content/widget_files/node_processor.rb
|
211
|
+
- app/services/mathjax/api/client.rb
|
212
212
|
- app/views/.keep
|
213
213
|
- app/views/embeddable_content/replacements/desmos_files/_applet.html.slim
|
214
214
|
- app/views/embeddable_content/replacements/desmos_files/_description.html.slim
|
@@ -278,6 +278,7 @@ files:
|
|
278
278
|
- bin/rails
|
279
279
|
- config/initializers/embeddable_content.rb
|
280
280
|
- config/routes.rb
|
281
|
+
- embeddable_content-1.0.0.gem
|
281
282
|
- embeddable_content.gemspec
|
282
283
|
- lib/embeddable_content.rb
|
283
284
|
- lib/embeddable_content/engine.rb
|
@@ -286,7 +287,7 @@ files:
|
|
286
287
|
homepage: https://github.com/illustrativemathematics/embedded_content
|
287
288
|
licenses: []
|
288
289
|
metadata: {}
|
289
|
-
post_install_message:
|
290
|
+
post_install_message:
|
290
291
|
rdoc_options: []
|
291
292
|
require_paths:
|
292
293
|
- lib
|
@@ -298,12 +299,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
298
299
|
version: '0'
|
299
300
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
300
301
|
requirements:
|
301
|
-
- - "
|
302
|
+
- - ">="
|
302
303
|
- !ruby/object:Gem::Version
|
303
|
-
version:
|
304
|
+
version: '0'
|
304
305
|
requirements: []
|
305
306
|
rubygems_version: 3.0.3
|
306
|
-
signing_key:
|
307
|
+
signing_key:
|
307
308
|
specification_version: 4
|
308
309
|
summary: Embeddable Content functionality extracted from cms-im app.
|
309
310
|
test_files: []
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EmbeddableContent
|
4
|
-
module HasMoveableNodes
|
5
|
-
CSS_CLASS_MOVEABLE_NODE_RELOCATED = 'node-relocated-by-embedder'
|
6
|
-
CSS_CLASS_MOVEABLE_NODES_RELOCATED = 'nodes-relocated-by-embedder'
|
7
|
-
|
8
|
-
private
|
9
|
-
|
10
|
-
def update_moveable_nodes?
|
11
|
-
false
|
12
|
-
end
|
13
|
-
|
14
|
-
def update_moveable_nodes
|
15
|
-
moveable_nodes.each { |node| update_moveable_node node }
|
16
|
-
remove_affected_empty_nodes
|
17
|
-
end
|
18
|
-
|
19
|
-
def remove_affected_empty_nodes
|
20
|
-
relocated_moveable_nodes.each { |node| node.remove if node.content.blank? }
|
21
|
-
end
|
22
|
-
|
23
|
-
def update_moveable_node(moveable_node)
|
24
|
-
moveable_node.parent.tap do |parent_node|
|
25
|
-
moveable_node.add_class CSS_CLASS_MOVEABLE_NODE_RELOCATED
|
26
|
-
parent_node.add_class CSS_CLASS_MOVEABLE_NODES_RELOCATED
|
27
|
-
relocate_moveable_node moveable_node
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def relocate_moveable_node(_moveable_node)
|
32
|
-
raise 'define this method in including class'
|
33
|
-
end
|
34
|
-
|
35
|
-
def place_moveable_node_before_parent(moveable_node)
|
36
|
-
moveable_node.parent.tap do |parent_node|
|
37
|
-
parent_node.add_previous_sibling moveable_node
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def place_moveable_node_after_parent(moveable_node)
|
42
|
-
moveable_node.parent.tap do |parent_node|
|
43
|
-
parent_node.add_next_sibling moveable_node
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def moveable_nodes
|
48
|
-
@moveable_nodes ||= document.css moveable_node_selector
|
49
|
-
end
|
50
|
-
|
51
|
-
def relocated_moveable_nodes
|
52
|
-
@relocated_moveable_nodes ||= document.css(relocated_moveable_node_selector)
|
53
|
-
end
|
54
|
-
|
55
|
-
def relocated_moveable_node_selector
|
56
|
-
@relocated_moveable_node_selector ||=
|
57
|
-
"#{parent_node_selector}.#{CSS_CLASS_MOVEABLE_NODES_RELOCATED}"
|
58
|
-
end
|
59
|
-
|
60
|
-
DEFAULT_PARENT_NODE_SELECTOR = 'p'
|
61
|
-
def parent_node_selector
|
62
|
-
DEFAULT_PARENT_NODE_SELECTOR
|
63
|
-
end
|
64
|
-
|
65
|
-
def moveable_node_selector
|
66
|
-
@moveable_node_selector ||= "#{parent_node_selector} > #{node_selector}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,175 +0,0 @@
|
|
1
|
-
# edc: see
|
2
|
-
# https://github.com/bootstraponline/encodeURIComponent_ruby/blob/master/uri_encode_component.rb
|
3
|
-
|
4
|
-
=begin
|
5
|
-
Copyright 2006-2008 the V8 project authors. All rights reserved.
|
6
|
-
Redistribution and use in source and binary forms, with or without
|
7
|
-
modification, are permitted provided that the following conditions are
|
8
|
-
met:
|
9
|
-
|
10
|
-
* Redistributions of source code must retain the above copyright
|
11
|
-
notice, this list of conditions and the following disclaimer.
|
12
|
-
* Redistributions in binary form must reproduce the above
|
13
|
-
copyright notice, this list of conditions and the following
|
14
|
-
disclaimer in the documentation and/or other materials provided
|
15
|
-
with the distribution.
|
16
|
-
* Neither the name of Google Inc. nor the names of its
|
17
|
-
contributors may be used to endorse or promote products derived
|
18
|
-
from this software without specific prior written permission.
|
19
|
-
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
-
=end
|
32
|
-
|
33
|
-
# This file provides the following methods:
|
34
|
-
# encodeURIComponent(componentString)
|
35
|
-
# string.charCodeAt(k)
|
36
|
-
|
37
|
-
# component must be String
|
38
|
-
def encodeURIComponent(componentString)
|
39
|
-
URI::URIEncodeComponent(componentString)
|
40
|
-
end
|
41
|
-
|
42
|
-
# define charCodeAt on String
|
43
|
-
class String
|
44
|
-
def charCodeAt(k)
|
45
|
-
return self[k].ord
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
module URI; class << self
|
50
|
-
# Does the char code correspond to an alpha-numeric char.
|
51
|
-
# isAlphaNumeric('a'.ord) => true
|
52
|
-
# isAlphaNumeric(''.ord) => false
|
53
|
-
def isAlphaNumeric(cc)
|
54
|
-
# a - z
|
55
|
-
if (97 <= cc && cc <= 122); return true end
|
56
|
-
# A - Z
|
57
|
-
if (65 <= cc && cc <= 90); return true end
|
58
|
-
# 0 - 9
|
59
|
-
if (48 <= cc && cc <= 57); return true end
|
60
|
-
|
61
|
-
return false
|
62
|
-
end
|
63
|
-
|
64
|
-
def unescapePredicate(cc)
|
65
|
-
if (isAlphaNumeric(cc)); return true end
|
66
|
-
# !
|
67
|
-
if (cc == 33); return true end
|
68
|
-
# '()*
|
69
|
-
if (39 <= cc && cc <= 42); return true end
|
70
|
-
# -.
|
71
|
-
if (45 <= cc && cc <= 46); return true end
|
72
|
-
# _
|
73
|
-
if (cc == 95); return true end
|
74
|
-
# ~
|
75
|
-
if (cc == 126); return true end
|
76
|
-
|
77
|
-
return false
|
78
|
-
end
|
79
|
-
|
80
|
-
def URIEncodeSingle(cc, result, index)
|
81
|
-
x = (cc >> 12) & 0xF;
|
82
|
-
y = (cc >> 6) & 63;
|
83
|
-
z = cc & 63;
|
84
|
-
octets = Array.new(3);
|
85
|
-
if (cc <= 0x007F)
|
86
|
-
octets[0] = cc;
|
87
|
-
elsif (cc <= 0x07FF)
|
88
|
-
octets[0] = y + 192;
|
89
|
-
octets[1] = z + 128;
|
90
|
-
else
|
91
|
-
octets[0] = x + 224;
|
92
|
-
octets[1] = y + 128;
|
93
|
-
octets[2] = z + 128;
|
94
|
-
end
|
95
|
-
return URIEncodeOctets(octets, result, index);
|
96
|
-
end
|
97
|
-
|
98
|
-
# Lazily initialized.
|
99
|
-
@@hexCharCodeArray = 0;
|
100
|
-
|
101
|
-
def URIAddEncodedOctetToBuffer(octet, result, index)
|
102
|
-
result[index] = 37; # Char code of '%'.
|
103
|
-
index += 1
|
104
|
-
result[index] = @@hexCharCodeArray[octet >> 4];
|
105
|
-
index += 1
|
106
|
-
result[index] = @@hexCharCodeArray[octet & 0x0F];
|
107
|
-
index += 1
|
108
|
-
return index;
|
109
|
-
end
|
110
|
-
|
111
|
-
def URIEncodeOctets(octets, result, index)
|
112
|
-
if (@@hexCharCodeArray == 0)
|
113
|
-
@@hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
114
|
-
65, 66, 67, 68, 69, 70];
|
115
|
-
end
|
116
|
-
index = URIAddEncodedOctetToBuffer(octets[0], result, index);
|
117
|
-
if (octets[1]); index = URIAddEncodedOctetToBuffer(octets[1], result, index) end
|
118
|
-
if (octets[2]); index = URIAddEncodedOctetToBuffer(octets[2], result, index) end
|
119
|
-
if (octets[3]); index = URIAddEncodedOctetToBuffer(octets[3], result, index) end
|
120
|
-
return index;
|
121
|
-
end
|
122
|
-
|
123
|
-
def URIEncodePair(cc1 , cc2, result, index)
|
124
|
-
u = ((cc1 >> 6) & 0xF) + 1;
|
125
|
-
w = (cc1 >> 2) & 0xF;
|
126
|
-
x = cc1 & 3;
|
127
|
-
y = (cc2 >> 6) & 0xF;
|
128
|
-
z = cc2 & 63;
|
129
|
-
octets = Array.new(4);
|
130
|
-
octets[0] = (u >> 2) + 240;
|
131
|
-
octets[1] = (((u & 3) << 4) | w) + 128;
|
132
|
-
octets[2] = ((x << 4) | y) + 128;
|
133
|
-
octets[3] = z + 128;
|
134
|
-
return URIEncodeOctets(octets, result, index);
|
135
|
-
end
|
136
|
-
|
137
|
-
# component must be String
|
138
|
-
def URIEncodeComponent(componentString)
|
139
|
-
Encode(componentString, :unescapePredicate);
|
140
|
-
end
|
141
|
-
|
142
|
-
# ECMA-262, section 15.1.3
|
143
|
-
def Encode(uri, unescape)
|
144
|
-
uriLength = uri.length;
|
145
|
-
# We are going to pass result to %StringFromCharCodeArray
|
146
|
-
# which does not expect any getters/setters installed
|
147
|
-
# on the incoming array.
|
148
|
-
result = Array.new(uriLength);
|
149
|
-
index = 0;
|
150
|
-
k = -1;
|
151
|
-
while ((k+=1) < uriLength) do
|
152
|
-
cc1 = uri.charCodeAt(k);
|
153
|
-
if (self.send(unescape, cc1))
|
154
|
-
result[index] = cc1;
|
155
|
-
index += 1
|
156
|
-
else
|
157
|
-
if (cc1 >= 0xDC00 && cc1 <= 0xDFFF); throw("URI malformed") end
|
158
|
-
if (cc1 < 0xD800 || cc1 > 0xDBFF)
|
159
|
-
index = URIEncodeSingle(cc1, result, index);
|
160
|
-
else
|
161
|
-
k+=1;
|
162
|
-
if (k == uriLength); throw("URI malformed") end
|
163
|
-
cc2 = uri.charCodeAt(k);
|
164
|
-
if (cc2 < 0xDC00 || cc2 > 0xDFFF); throw("URI malformed") end
|
165
|
-
index = URIEncodePair(cc1, cc2, result, index);
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
# return %StringFromCharCodeArray(result);
|
170
|
-
# 'c' = 8 bit signed char
|
171
|
-
# http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack
|
172
|
-
return result.pack 'c*'
|
173
|
-
end
|
174
|
-
end # class << self
|
175
|
-
end # module
|