maglove-engine 2.0.5

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 825f4967e1ffdad50b807c795c277b4f0861a1b5
4
+ data.tar.gz: c2be11d3033dc57a57780b13d4ef569abeac0e7d
5
+ SHA512:
6
+ metadata.gz: 6e8b680e4b5f1f66ed16bb808cb1360b5b3c1cccb37454c00fa7c491a46322e5d7d17585986003481cad66b41862e7ade925381e867251aee234dfe51326d638
7
+ data.tar.gz: 288b0f1c11d2cabef09fdb06c575a20b694ded9c11b16c1d2253e083ecf4715d285eb135cf90c6baf14d4e8ff3f8f6fc1b136f41226235bdf029a44adcfbaca9
@@ -0,0 +1,9 @@
1
+ module Maglove
2
+ module Engine
3
+ class Configuration
4
+ include Singleton
5
+ attr_accessor :asset_uri
6
+ attr_accessor :block_path
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ module Maglove
2
+ module Engine
3
+ class Registry
4
+ include Singleton
5
+ attr_reader :widgets
6
+
7
+ def initialize
8
+ @widgets = {}
9
+ end
10
+
11
+ def register_widget(identifier, klass)
12
+ widgets[identifier] = klass
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,99 @@
1
+ module Maglove
2
+ module Engine
3
+ class Scope
4
+ def initialize(engine, variables = {})
5
+ @engine = engine
6
+ @variables = variables
7
+ end
8
+
9
+ def theme
10
+ @variables[:theme]
11
+ end
12
+
13
+ def asset_uri
14
+ var(:asset_uri, Maglove::Engine.config.asset_uri)
15
+ end
16
+
17
+ def block_path
18
+ var(:block_path, Maglove::Engine.config.block_path)
19
+ end
20
+
21
+ def asset(url)
22
+ "#{asset_uri}/themes/#{theme}/#{url}"
23
+ end
24
+
25
+ def root_asset(url)
26
+ "#{asset_uri}/#{url}"
27
+ end
28
+
29
+ def widget(identifier, options = {}, &block)
30
+ unless Maglove::Engine::Registry.instance.widgets.keys.include?(identifier.to_sym)
31
+ raise "Widget not found: #{identifier}"
32
+ end
33
+ widget = Maglove::Engine.widget(identifier, options, self)
34
+ widget.render(&block)
35
+ end
36
+
37
+ def block(identifier, variables = {})
38
+ path = File.join(block_path, "#{identifier}.haml")
39
+ haml = File.read(path)
40
+ Maglove::Engine.render(haml, @variables.merge(variables))
41
+ end
42
+
43
+ def var(key, default = nil)
44
+ @variables[key.to_sym] || default
45
+ end
46
+
47
+ def variable(key, default = nil)
48
+ var(key, default)
49
+ end
50
+
51
+ def style_string(options, *args, &block)
52
+ StyleBuilder.new(options, args).process(&block)
53
+ end
54
+
55
+ def method_missing(name, *args, &block)
56
+ if name.to_s.end_with?("_widget") and args.length <= 1
57
+ identifier = "legacy_#{name[0..-8]}".to_sym
58
+ widget(identifier, args.first || {}, &block)
59
+ elsif args.length == 0 and @variables.key?(name.to_sym)
60
+ @variables[name.to_sym]
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ def respond_to_missing?(name, include_private = false)
67
+ name.to_s.end_with?("_widget") || super
68
+ end
69
+
70
+ def drop_container
71
+ haml_tag :div, class: '_typeloft_widget_drop_container'
72
+ end
73
+
74
+ def style(*args, &block)
75
+ style = nil
76
+ if args[-1].class.name == 'Hash'
77
+ style_options = args.pop
78
+ style = style_string(style_options, *style_options.keys)
79
+ end
80
+ classes = args.map { |a| "__#{a}" }
81
+ haml_tag :span, class: classes.join(' '), style: style do
82
+ yield if block_given?
83
+ end
84
+ end
85
+
86
+ def link(href, target: nil, &block)
87
+ haml_tag :a, href: href, target: target do
88
+ yield if block_given?
89
+ end
90
+ end
91
+
92
+ def font(font_face, &block)
93
+ haml_tag :font, face: font_face do
94
+ yield if block_given?
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,67 @@
1
+ module Maglove
2
+ module Engine
3
+ class StyleBuilder
4
+ attr_accessor :options
5
+ attr_accessor :styles
6
+
7
+ def initialize(options, styles = [])
8
+ @options = {}
9
+ @styles = {}
10
+
11
+ # expand margins
12
+ if styles.include?(:margin)
13
+ styles |= [:margin_top, :margin_right, :margin_bottom, :margin_left]
14
+ styles.reject! { |_style| styles == :margin }
15
+ end
16
+
17
+ # expand paddings
18
+ if styles.include?(:padding)
19
+ styles |= [:padding_top, :padding_right, :padding_bottom, :padding_left]
20
+ styles.reject! { |_style| styles == :padding }
21
+ end
22
+
23
+ # build sanitized options
24
+ options.each do |k, v|
25
+ @options[sanitize_style(k)] = v
26
+ end
27
+
28
+ # add initial styles
29
+ add_multi(styles)
30
+ end
31
+
32
+ def process(&block)
33
+ yield self if block_given?
34
+ result = @styles.map { |k, v| "#{k}: #{v};" }.join(' ')
35
+ result.empty? ? nil : result
36
+ end
37
+
38
+ def add_multi(styles)
39
+ styles.each do |style|
40
+ add(style)
41
+ end
42
+ end
43
+
44
+ def add(style, value = nil, template = nil)
45
+ style = sanitize_style(style)
46
+
47
+ # handle empty value field
48
+ if (!value || value.empty?) && !(!(@options[style]) || @options[style].empty?)
49
+ value = @options[style]
50
+ end
51
+
52
+ # apply template
53
+ if value && !value.empty? && template && !template.empty?
54
+ value = ERB.new(template).result(binding)
55
+ end
56
+
57
+ @styles[style] = value if value && !value.empty?
58
+ end
59
+
60
+ def sanitize_style(value)
61
+ value.to_s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1-\2')
62
+ .gsub(/([a-z\d])([A-Z])/, '\1-\2')
63
+ .tr('_', '-').downcase
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,5 @@
1
+ module Maglove
2
+ module Engine
3
+ VERSION = "2.0.5"
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ require 'singleton'
2
+ require 'haml'
3
+ require 'erb'
4
+ require 'nokogiri'
5
+ require 'active_support/inflector'
6
+ require 'maglove/widget'
7
+ require 'maglove/engine/registry'
8
+ require 'maglove/engine/configuration'
9
+ require 'maglove/engine/scope'
10
+ require 'maglove/engine/style_builder'
11
+
12
+ module Maglove
13
+ module Engine
14
+ def self.config
15
+ Configuration.instance
16
+ end
17
+
18
+ def self.configure(&block)
19
+ yield Configuration.instance if block_given?
20
+ Configuration.instance
21
+ end
22
+
23
+ def self.widget(identifier, options = {}, scope)
24
+ Maglove::Engine::Registry.instance.widgets[identifier].new(scope, options)
25
+ end
26
+
27
+ def self.render(haml, variables = {})
28
+ engine = Haml::Engine.new(haml, remove_whitespace: true)
29
+ scope = Scope.new(engine, variables)
30
+ engine.render(scope)
31
+ rescue StandardError => e
32
+ raise RenderError.new(e.message, e)
33
+ end
34
+
35
+ def self.register_widget(identifier, klass)
36
+ Registry.instance.register_widget(identifier, klass)
37
+ end
38
+
39
+ def self.register_widgets
40
+ path = File.join(File.dirname(__FILE__), "/widget/*.rb")
41
+ Dir[path].each do |file|
42
+ require file
43
+ identifier = File.basename(file).split(".").first
44
+ klass_name = identifier.camelcase
45
+ Maglove::Engine.register_widget(identifier.to_sym, "Maglove::Widget::#{klass_name}".constantize)
46
+ Maglove::Engine.register_widget("legacy_#{identifier}".to_sym, "Maglove::Widget::Legacy#{klass_name}".constantize)
47
+ end
48
+ end
49
+
50
+ class RenderError < StandardError
51
+ attr_reader :original_error
52
+ def initialize(message = "Error", original_error = nil)
53
+ super(message)
54
+ @original_error = original_error
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ module Maglove
2
+ module Widget
3
+ class Button < V2
4
+ def identifier
5
+ "button"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ background_color: "#e6e6e6",
11
+ border_radius: "4px",
12
+ border_width: "1px",
13
+ border_style: "solid",
14
+ media: false,
15
+ size: "btn-lg",
16
+ style: "primary",
17
+ type: "btn-fit"
18
+ }
19
+ end
20
+ end
21
+
22
+ class LegacyButton < V1
23
+ def identifier
24
+ "button"
25
+ end
26
+
27
+ def defaults
28
+ {
29
+ background_color: "#e6e6e6",
30
+ border_radius: "4px",
31
+ border_width: "1px",
32
+ border_style: "solid",
33
+ media: false,
34
+ size: "btn-lg",
35
+ style: "primary",
36
+ type: "btn-fit"
37
+ }
38
+ end
39
+
40
+ def button_attributes
41
+ {
42
+ "class" => "_typeloft_editable btn btn-#{options[:style]} #{options[:size]} #{options[:type]} #{options[:media] ? 'btn-media' : ''}",
43
+ "href" => (options[:href] or "#"),
44
+ "style" => style_string(options, :border_radius, :border_width, :border_style, :border_color, :background_color) do |sb|
45
+ sb.add(:border_style, "solid")
46
+ end,
47
+ "data-media" => options[:media]
48
+ }
49
+ end
50
+
51
+ def render(&block)
52
+ super do
53
+ haml_tag :a, button_attributes do
54
+ if options[:media] and !options[:media].blank?
55
+ haml_tag :video do
56
+ haml_tag :source, { src: options[:media], type: "video/mp4" }
57
+ end
58
+ end
59
+ yield self if block_given?
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,80 @@
1
+ module Maglove
2
+ module Widget
3
+ class Columns < V2
4
+ def identifier
5
+ "columns"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ layout: "6x6",
11
+ collapse_options: "sm"
12
+ }
13
+ end
14
+
15
+ def column(&block)
16
+ yield self if block_given?
17
+ end
18
+ end
19
+
20
+ class LegacyColumns < V1
21
+ attr_reader :columns
22
+ attr_reader :column_count
23
+ attr_reader :total_columns
24
+
25
+ def initialize(scope, options = {})
26
+ super
27
+ @column_count = 0
28
+ column_array = @options[:columns].to_s.split("x").map(&:to_i)
29
+ if column_array.length == 1
30
+ @total_columns = column_array[0]
31
+ @columns = Array.new(@total_columns) { 12 / @total_columns }
32
+ else
33
+ @total_columns = column_array.length
34
+ @columns = column_array
35
+ end
36
+ end
37
+
38
+ def identifier
39
+ "columns"
40
+ end
41
+
42
+ def defaults
43
+ {
44
+ columns: "2",
45
+ style: "default",
46
+ margin_bottom: "",
47
+ collapse_options: "sm"
48
+ }
49
+ end
50
+
51
+ def render(&block)
52
+ super do
53
+ haml_tag :div, row_options do
54
+ yield self if block_given?
55
+ end
56
+ end
57
+ end
58
+
59
+ def column(&block)
60
+ span = columns[column_count]
61
+ raise "ERROR: Row does not allow column at position #{column_count}" unless span
62
+ @column_count += 1
63
+ phone_cols = (options[:collapse_options] == "xs") ? span : "12"
64
+ haml_tag :div, class: "column col-#{phone_cols} col-tablet-#{span} col-#{options[:collapse_options]}-#{span}" do
65
+ yield self if block_given?
66
+ drop_container
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def row_options
73
+ {
74
+ class: "row row-#{options[:style]}",
75
+ style: style_string(options, :margin_bottom)
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,123 @@
1
+ module Maglove
2
+ module Widget
3
+ class Container < V2
4
+ def identifier
5
+ "container"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ animate: "none",
11
+ parallax_effect: "none",
12
+ border_radius: nil,
13
+ border_width: nil,
14
+ border_style: nil,
15
+ border_color: "transparent",
16
+ min_height: nil,
17
+ max_height: nil,
18
+ overflow_y: nil
19
+ }
20
+ end
21
+ end
22
+
23
+ class LegacyContainer < V1
24
+ def identifier
25
+ "container"
26
+ end
27
+
28
+ def defaults
29
+ {
30
+ animate: "none",
31
+ image_source: false,
32
+ image_position: "center_center",
33
+ image_size: "cover",
34
+ parallax_effect: "none",
35
+ parallax_speed: 0.6,
36
+ background_color: nil,
37
+ bg_color: nil,
38
+ opacity: nil,
39
+ border_radius: nil,
40
+ border_width: nil,
41
+ border_color: "#111111",
42
+ border_style: nil,
43
+ style: "default",
44
+ padding_top: nil,
45
+ padding_right: nil,
46
+ padding_bottom: nil,
47
+ padding_left: nil,
48
+ alignment: "center",
49
+ min_height: nil,
50
+ max_height: nil,
51
+ max_width: nil,
52
+ margin_top: nil,
53
+ margin_right: nil,
54
+ margin_bottom: nil,
55
+ margin_left: nil,
56
+ overflow_y: nil
57
+ }
58
+ end
59
+
60
+ def render(&block)
61
+ super do
62
+ haml_tag :section, container_options do
63
+ haml_tag :div, image_options do
64
+ yield self if block_given?
65
+ drop_container
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def container_options
74
+ result = { class: container_classes, style: container_styles }
75
+ if !options[:parallax_effect].empty? and options[:parallax_effect] != "none"
76
+ result["data-parallax-style"] = options[:parallax_effect]
77
+ result["data-parallax-speed"] = options[:parallax_speed]
78
+ end
79
+ result
80
+ end
81
+
82
+ def image_options
83
+ { class: "one-container-image", style: image_styles }
84
+ end
85
+
86
+ def container_classes
87
+ classes = ["one-container"]
88
+ classes.push("animate #{options[:animate]}") if options[:animate] != "none"
89
+ classes.push("container-#{options[:style]}") unless options[:style].empty?
90
+ classes.push("container-image-#{options[:image_size]}") unless options[:image_size].empty?
91
+ classes.push("container-parallax") if !options[:parallax_effect].empty? and options[:parallax_effect] != "none"
92
+ classes.join(" ")
93
+ end
94
+
95
+ def container_styles
96
+ style_string options, :opacity, :border, :opacity, :border_radius, :border_width, :border_color, :border_style, :margin do |sb|
97
+ sb.add(:background_color, (options[:background_color] == "custom") ? options[:bg_color] : nil)
98
+ if options[:background_color] == "overlay"
99
+ sb.add(:background_image, options[:image_source], "linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(<%= value %>)")
100
+ else
101
+ sb.add(:background_image, options[:image_source], "url(<%= value %>)")
102
+ end
103
+ sb.add(:background_position, options[:image_position], "<%= value.split('_').join(' ') %>")
104
+ end
105
+ end
106
+
107
+ def image_styles
108
+ if options[:alignment] == "left"
109
+ options[:margin_left] = "0"
110
+ options[:margin_right] = "auto"
111
+ elsif options[:alignment] == "right"
112
+ options[:margin_left] = "auto"
113
+ options[:margin_right] = "0"
114
+ else
115
+ options[:margin_left] = "auto"
116
+ options[:margin_right] = "auto"
117
+ end
118
+
119
+ style_string options, :min_height, :max_height, :max_width, :padding, :overflow_y, :margin_left, :margin_right
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,45 @@
1
+ module Maglove
2
+ module Widget
3
+ class Heading < V2
4
+ def identifier
5
+ "heading"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ type: "h1",
11
+ align: "left",
12
+ line_height: "1.3",
13
+ padding: [0, 0, 8, 0]
14
+ }
15
+ end
16
+ end
17
+
18
+ class LegacyHeading < V1
19
+ def identifier
20
+ "heading"
21
+ end
22
+
23
+ def defaults
24
+ {
25
+ type: "h1",
26
+ style: "default",
27
+ align: "left",
28
+ margin_bottom: "1em",
29
+ line_height: nil,
30
+ letter_spacing: nil
31
+ }
32
+ end
33
+
34
+ def render(&block)
35
+ super do
36
+ haml_tag :header, class: "#{options[:style]} align-#{options[:align]}", style: style_string(options, :margin, :padding) do
37
+ haml_tag options[:type], class: "_typeloft_editable _typeloft_widget_autoselect", style: style_string(options, :line_height, :letter_spacing) do
38
+ yield self if block_given?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ module Maglove
2
+ module Widget
3
+ class HorizontalRule < V2
4
+ def identifier
5
+ "horizontal_rule"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ style: 'solid',
11
+ color: 'dark'
12
+ }
13
+ end
14
+ end
15
+
16
+ class LegacyHorizontalRule < V1
17
+ def identifier
18
+ "horizontal_rule"
19
+ end
20
+
21
+ def defaults
22
+ {
23
+ style: 'solid',
24
+ color: 'dark',
25
+ max_height: 'inherit'
26
+ }
27
+ end
28
+
29
+ def render(&block)
30
+ super do
31
+ haml_tag :hr, style: "max-height: #{options[:max_height]}", class: "#{options[:style]} #{options[:color]}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,76 @@
1
+ module Maglove
2
+ module Widget
3
+ class Image < V2
4
+ def identifier
5
+ "image"
6
+ end
7
+
8
+ def defaults
9
+ {
10
+ style: "img-responsive",
11
+ align: "center",
12
+ source: false,
13
+ magnify: false,
14
+ tooltip_icon: "bullhorn",
15
+ tooltip_text_alignment: "justify",
16
+ tooltip_text_size: "medium",
17
+ tooltip_position: "top-right",
18
+ tooltip_text: nil
19
+ }
20
+ end
21
+ end
22
+
23
+ class LegacyImage < V1
24
+ def identifier
25
+ "image"
26
+ end
27
+
28
+ def defaults
29
+ {
30
+ style: "img-responsive",
31
+ align: "center",
32
+ title: nil,
33
+ source: false,
34
+ magnify: false,
35
+ margin_bottom: "0",
36
+ max_width: "100%",
37
+ min_width: "0",
38
+ tooltip_icon: "bullhorn",
39
+ tooltip_text_alignment: "justify",
40
+ tooltip_text_size: "medium",
41
+ tooltip_position: "top-right",
42
+ tooltip_text: nil
43
+ }
44
+ end
45
+
46
+ def render(&block)
47
+ super do
48
+ image_class = "image-widget align-#{options[:align]}"
49
+ image_class += " popup-position-#{options[:tooltip_position]}" unless options[:tooltip_text].nil?
50
+ haml_tag :div, class: image_class, style: "min-width: #{options[:min_width]}; max-width: #{options[:max_width]}; #{style_string(options, :margin, :padding)}" do
51
+ wrap_image_link do
52
+ unless options[:tooltip_text].nil?
53
+ haml_tag :i, class: "popup fa fa-lg fa-#{options[:tooltip_icon]}"
54
+ haml_tag :div, class: "popup-box", style: "font-size: #{options[:tooltip_text_size]}, text-align: #{options[:tooltip_text_alignment]};" do
55
+ haml_concat(options[:tooltip_text])
56
+ end
57
+ end
58
+ haml_tag :img, class: "image #{options[:style]} #{options[:magnify] ? 'magnific-image' : ''}", src: options[:source], title: options[:title]
59
+ haml_tag :div, class: "image-drop-target"
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def wrap_image_link(&block)
68
+ if options[:href].nil?
69
+ yield
70
+ else
71
+ link(options[:href], &block)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end