embeddable_content 0.4.0.beta7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/lib/embeddable_content/engine.rb +0 -2
- data/lib/embeddable_content/version.rb +1 -1
- metadata +9 -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: 9f62f76f29d057ecacbf2309985c705b56ee816e8f8007b463e685e03d1cad26
|
4
|
+
data.tar.gz: 7240e1f0e3f152b9d82c4762a90ded6b071e9d7307c8d97382949a89481791e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19168d85258826a8eea105d239e9ffccd5b34e18801f22c9a15eef6701309b231ff3a7841cb0bd7353c70e368548105620d58697c4ac3e580ed0616f20309db1
|
7
|
+
data.tar.gz: feb567906aa7d54399311f661a0a8e6dfd14c369cbc818f50724f7a48118d6a04548b682691f283db4fad4a3175b4a9d1f7cc8c8eefb9fa66b1bd0ed2445b6d9
|
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 record.cdn_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
|
| .
|
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.1.0
|
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-07-25 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
|
@@ -286,7 +286,7 @@ files:
|
|
286
286
|
homepage: https://github.com/illustrativemathematics/embedded_content
|
287
287
|
licenses: []
|
288
288
|
metadata: {}
|
289
|
-
post_install_message:
|
289
|
+
post_install_message:
|
290
290
|
rdoc_options: []
|
291
291
|
require_paths:
|
292
292
|
- lib
|
@@ -298,12 +298,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
298
298
|
version: '0'
|
299
299
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
300
300
|
requirements:
|
301
|
-
- - "
|
301
|
+
- - ">="
|
302
302
|
- !ruby/object:Gem::Version
|
303
|
-
version:
|
303
|
+
version: '0'
|
304
304
|
requirements: []
|
305
305
|
rubygems_version: 3.0.3
|
306
|
-
signing_key:
|
306
|
+
signing_key:
|
307
307
|
specification_version: 4
|
308
308
|
summary: Embeddable Content functionality extracted from cms-im app.
|
309
309
|
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
|