fl 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +173 -0
  5. data/README.md +30 -0
  6. data/Rakefile +2 -0
  7. data/app/admin/options.rb +46 -0
  8. data/app/admin/pages.rb +55 -0
  9. data/app/admin/users.rb +34 -0
  10. data/app/assets/javascripts/active_admin.coffee.erb +20 -0
  11. data/app/assets/javascripts/application.coffee.erb +40 -0
  12. data/app/assets/javascripts/ckeditor/basepath.coffee.erb +21 -0
  13. data/app/assets/javascripts/ckeditor/config.coffee.erb +146 -0
  14. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +232 -0
  15. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +102 -0
  16. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/plugin.js +158 -0
  17. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/assets/sample.css +70 -0
  18. data/app/assets/javascripts/ckeditor/plugins/stylesheetparser/samples/stylesheetparser.html +85 -0
  19. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog.css +5 -0
  20. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie.css +5 -0
  21. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie7.css +5 -0
  22. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_ie8.css +5 -0
  23. data/app/assets/javascripts/ckeditor/skins/minimalist/dialog_iequirks.css +5 -0
  24. data/app/assets/javascripts/ckeditor/skins/minimalist/editor.css +5 -0
  25. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_gecko.css +5 -0
  26. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie.css +5 -0
  27. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie7.css +5 -0
  28. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_ie8.css +5 -0
  29. data/app/assets/javascripts/ckeditor/skins/minimalist/editor_iequirks.css +5 -0
  30. data/app/assets/javascripts/ckeditor/skins/minimalist/icons.png +0 -0
  31. data/app/assets/javascripts/ckeditor/skins/minimalist/icons_hidpi.png +0 -0
  32. data/app/assets/javascripts/ckeditor/skins/minimalist/images/arrow.png +0 -0
  33. data/app/assets/javascripts/ckeditor/skins/minimalist/images/close.png +0 -0
  34. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/close.png +0 -0
  35. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock-open.png +0 -0
  36. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/lock.png +0 -0
  37. data/app/assets/javascripts/ckeditor/skins/minimalist/images/hidpi/refresh.png +0 -0
  38. data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock-open.png +0 -0
  39. data/app/assets/javascripts/ckeditor/skins/minimalist/images/lock.png +0 -0
  40. data/app/assets/javascripts/ckeditor/skins/minimalist/images/refresh.png +0 -0
  41. data/app/assets/javascripts/ckeditor/skins/minimalist/readme.md +7 -0
  42. data/app/assets/javascripts/ckeditor/skins/minimalist/skin.js +10 -0
  43. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog.css +5 -0
  44. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie.css +5 -0
  45. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie7.css +5 -0
  46. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_ie8.css +5 -0
  47. data/app/assets/javascripts/ckeditor/skins/moonocolor/dialog_iequirks.css +5 -0
  48. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor.css +5 -0
  49. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_gecko.css +5 -0
  50. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie.css +5 -0
  51. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie7.css +5 -0
  52. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_ie8.css +5 -0
  53. data/app/assets/javascripts/ckeditor/skins/moonocolor/editor_iequirks.css +5 -0
  54. data/app/assets/javascripts/ckeditor/skins/moonocolor/icons.png +0 -0
  55. data/app/assets/javascripts/ckeditor/skins/moonocolor/icons_hidpi.png +0 -0
  56. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/arrow.png +0 -0
  57. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/close.png +0 -0
  58. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/close.png +0 -0
  59. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock-open.png +0 -0
  60. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/lock.png +0 -0
  61. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/hidpi/refresh.png +0 -0
  62. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock-open.png +0 -0
  63. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/lock.png +0 -0
  64. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/refresh.png +0 -0
  65. data/app/assets/javascripts/ckeditor/skins/moonocolor/images/spinner.gif +0 -0
  66. data/app/assets/javascripts/ckeditor/skins/moonocolor/readme.md +51 -0
  67. data/app/assets/javascripts/ckeditor/skins/moonocolor/skin.js +10 -0
  68. data/app/assets/javascripts/components/confirm.coffee +51 -0
  69. data/app/assets/javascripts/components/modals.coffee +29 -0
  70. data/app/assets/stylesheets/_defaults.yml +106 -0
  71. data/app/assets/stylesheets/_functions.sass.erb +75 -0
  72. data/app/assets/stylesheets/active_admin.sass +117 -0
  73. data/app/assets/stylesheets/application.sass.erb +46 -0
  74. data/app/assets/stylesheets/styles/reset.sass +139 -0
  75. data/app/assets/stylesheets/styles/structure.sass +69 -0
  76. data/app/assets/stylesheets/styles/ui/flash.sass +128 -0
  77. data/app/assets/stylesheets/styles/ui/fonts.sass +32 -0
  78. data/app/assets/stylesheets/styles/ui/modals.sass +61 -0
  79. data/app/assets/stylesheets/styles/ui/tooltips.sass +139 -0
  80. data/app/controllers/application_controller.rb +87 -0
  81. data/app/helpers/fl/application_helper.rb +53 -0
  82. data/app/helpers/fl/asset_helper.rb +50 -0
  83. data/app/helpers/fl/liquid_helper.rb +29 -0
  84. data/app/helpers/fl/meta_helper.rb +118 -0
  85. data/app/lib/active_record/concerns/base.rb +55 -0
  86. data/app/lib/active_record/concerns/seeds.rb +78 -0
  87. data/app/liquid/filters/meta_filter.rb +6 -0
  88. data/app/liquid/tags/google_analytics_tag.rb +32 -0
  89. data/app/liquid/tags/icon_tag.rb +37 -0
  90. data/app/liquid/tags/meta_tag.rb +120 -0
  91. data/app/mailers/application_mailer.rb +28 -0
  92. data/app/models/application_record.rb +3 -0
  93. data/app/models/asset.rb +95 -0
  94. data/app/models/association.rb +21 -0
  95. data/app/models/meta.rb +27 -0
  96. data/app/models/node.rb +59 -0
  97. data/app/models/profile.rb +49 -0
  98. data/app/models/user.rb +49 -0
  99. data/app/service/flash.rb +8 -0
  100. data/app/views/layouts/_admin.haml +6 -0
  101. data/app/views/layouts/_application.haml +17 -0
  102. data/app/views/layouts/base.haml +26 -0
  103. data/app/views/mailers/layouts/mailer.haml +8 -0
  104. data/app/views/mailers/layouts/mailer.text.erb +1 -0
  105. data/app/views/mailers/new_user.erb +4 -0
  106. data/bin/console +14 -0
  107. data/bin/setup +8 -0
  108. data/config/initializers/active_admin.rb +266 -0
  109. data/config/initializers/ckeditor.rb +63 -0
  110. data/config/initializers/devise.rb +279 -0
  111. data/config/initializers/friendly_id.rb +92 -0
  112. data/config/initializers/inflections.rb +20 -0
  113. data/config/initializers/liquid.rb +87 -0
  114. data/config/initializers/sass.rb +45 -0
  115. data/config/locales/devise.en.yml +62 -0
  116. data/config/locales/en.yml +13 -0
  117. data/config/puma.rb +59 -0
  118. data/config/routes.rb +56 -0
  119. data/db/migrate/20160616060637_create_nodes.rb +26 -0
  120. data/db/migrate/20160707080248_create_users.rb +52 -0
  121. data/db/migrate/20160707094704_create_slugs.rb +33 -0
  122. data/db/migrate/20160710095916_create_associations.rb +20 -0
  123. data/db/migrate/20160713061948_create_profiles.rb +27 -0
  124. data/db/migrate/20161115101221_create_assets.rb +25 -0
  125. data/db/migrate/20170725060408_create_active_admin_comments.rb +22 -0
  126. data/db/seeds.rb +81 -0
  127. data/fl.gemspec +73 -0
  128. data/lib/fl.rb +28 -0
  129. data/lib/fl/constants.rb +52 -0
  130. data/lib/fl/engine.rb +160 -0
  131. data/lib/fl/hash.rb +34 -0
  132. data/lib/generators/fl/sass_vars_generator.rb +16 -0
  133. data/lib/generators/fl/templates/sass.yml +56 -0
  134. data/lib/tasks/ckeditor.rake +37 -0
  135. data/lib/tasks/favicon.rake +37 -0
  136. data/readme/fl.jpg +0 -0
  137. metadata +416 -0
@@ -0,0 +1,55 @@
1
+ module ActiveRecord
2
+ module Concerns
3
+ module Base
4
+
5
+ ## This is used to provide base functionality to migrations
6
+ #########################################
7
+ #########################################
8
+
9
+ # Adapter
10
+ def adapter
11
+ ENV["DATABASE_ADAPTER"]
12
+ end
13
+
14
+ # Down
15
+ def down
16
+ drop_table table, if_exists: true
17
+ end
18
+
19
+ # UUID
20
+ def uuid(key=:id)
21
+ adapter == "sqlite3" ? {} : { key => :uuid }
22
+ end
23
+
24
+ # Table
25
+ def table
26
+ self.class.name.gsub!("Create", "").underscore
27
+ end
28
+
29
+ #########################################
30
+ #########################################
31
+
32
+ private
33
+
34
+ # http://stackoverflow.com/a/5665974/1143732
35
+ # Set "plugin" for UUID BEFORE using it
36
+ def setup_uuid
37
+ case adapter
38
+ when "mysql2"
39
+ execute("DROP TRIGGER IF EXISTS before_insert_#{table};") #http://stackoverflow.com/a/5945220/1143732
40
+ execute("CREATE TRIGGER before_insert_#{table} BEFORE INSERT ON associations FOR EACH ROW SET new.uuid = uuid();")
41
+ when "sqlite3"
42
+ # Nothing to do
43
+ when "postgresql"
44
+ enable_extension 'uuid-ossp' # => http://theworkaround.com/2015/06/12/using-uuids-in-rails.html#postgresql
45
+ else
46
+ raise NotImplementedError, "Unknown adapter type '#{adapter}'"
47
+ end
48
+ end
49
+
50
+ #########################################
51
+ #########################################
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,78 @@
1
+ module ActiveRecord
2
+ module Concerns
3
+ module Seeds
4
+
5
+ ## This is used to provide base functionality during seeding
6
+ #########################################
7
+ #########################################
8
+
9
+ # => first_or_initialize
10
+ # => https://snippets.aktagon.com/snippets/620-rails-find-or-initialize-and-find-or-create-methods-are-deprecated
11
+ def create model, attrs, vals=nil
12
+
13
+ # => Model
14
+ # => http://stackoverflow.com/a/32869926/1143732
15
+ model = model.to_s.titleize.gsub(" ","::")
16
+ model = model.constantize rescue nil
17
+
18
+ # => Model exists
19
+ unless model.nil?
20
+
21
+ # => Setup
22
+ payload = model.where(attrs).first_or_initialize
23
+ is_new = payload.new_record?
24
+
25
+ # => Action
26
+ payload.update vals || attrs
27
+
28
+ # => Output
29
+ if payload.valid?
30
+ puts "#{payload.class.name} #{is_new ? 'Created' : 'Updated'} - #{payload.ref}" + (payload.has_attribute?(:val) ? " → #{payload.val}" : nil)
31
+ else
32
+ puts "#{payload.class.name} Error - #{payload.errors.full_messages}"
33
+ end
34
+
35
+ else
36
+ puts "Model Not Initialized"
37
+ end
38
+
39
+ end
40
+
41
+ ########################################
42
+ ########################################
43
+
44
+ # => Iterate over hash or array
45
+ # => http://stackoverflow.com/a/16413593/1143732
46
+ def iterate model, h, ref=nil
47
+ return h unless h.is_a?(Hash) || h.is_a?(Array) # => Return if not hash
48
+
49
+ # => Linebreak
50
+ puts "\n"
51
+
52
+ # => Proceed if hash/array
53
+ h.each do |k,v|
54
+
55
+ # If v is nil, an array is being iterated and the value is k.
56
+ # If v is not nil, a hash is being iterated and the value is v.
57
+ value = v || k
58
+
59
+ # Ref
60
+ # If exists, need to prepend ref_
61
+ reference = v ? "#{ref}#{'_' if ref}#{k}" : ref
62
+
63
+ # => Iterate or continue
64
+ if value.is_a?(Hash) || value.is_a?(Array)
65
+ iterate model, value, k
66
+ else
67
+ create model, { ref: reference, val: value }, { seed: true }
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ #########################################
74
+ #########################################
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,6 @@
1
+ ## Meta Helpers ##
2
+ module MetaFilter
3
+ def textilize(input) # will be available as the "textilize" filter
4
+ "test"
5
+ end
6
+ end
@@ -0,0 +1,32 @@
1
+ # Returns a Google Analytics tag.
2
+ #
3
+ # Usage:
4
+ #
5
+ # {% ga 'UA-XXXXX-X' %}
6
+
7
+ class Tags::GoogleAnalyticsTag < ::Liquid::Tag
8
+ Syntax = /(#{::Liquid::QuotedFragment}+)?/
9
+
10
+ def initialize(tag_name, markup, tokens)
11
+ if markup =~ Syntax
12
+ @account_id = $1.gsub('\'', '')
13
+ else
14
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'Google Analytics Tag' - Valid syntax: {% ga <account_id> %}")
15
+ end
16
+
17
+ super
18
+ end
19
+
20
+ def render(context)
21
+ %{
22
+ <script>
23
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
24
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
25
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
26
+ })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
27
+ ga('create', '#{@account_id}', 'auto');
28
+ ga('send', 'pageview');
29
+ </script>
30
+ }
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ class Tags::IconTag < Liquid::Tag
2
+ Syntax = /(#{::Liquid::QuotedFragment}+)?/
3
+
4
+ #################################
5
+
6
+ ## Init ##
7
+ def initialize tag_name, markup, tokens
8
+ if markup =~ Syntax
9
+ @icon = $1.gsub('\'', '')
10
+ else
11
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'Icon Tag' - Valid syntax: {% i <args> %}")
12
+ end
13
+
14
+ super
15
+ end
16
+
17
+ #################################
18
+
19
+ ## Helpers ##
20
+ def helpers
21
+ @helpers ||= ApplicationController.helpers
22
+ end
23
+
24
+ #################################
25
+
26
+ ## Output ##
27
+ def render context
28
+ gem_name = 'font-awesome-rails'
29
+ gdep = Gem::Dependency.new gem_name
30
+
31
+ # Invoke
32
+ helpers.send (gdep.matching_specs.max_by(&:version) ? :fa_icon : :ion_icon), @icon
33
+ end
34
+
35
+ #################################
36
+
37
+ end
@@ -0,0 +1,120 @@
1
+ ###################################################
2
+ ###################################################
3
+ ## ___ ___ _ ##
4
+ ## | \/ | | | ##
5
+ ## | . . | ___| |_ __ _ ##
6
+ ## | |\/| |/ _ \ __/ _` | ##
7
+ ## | | | | __/ || (_| | ##
8
+ ## \_| |_/\___|\__\__,_| ##
9
+ ###################################################
10
+ ###################################################
11
+
12
+ class Tags::MetaTag < Liquid::Tag
13
+ Syntax = /(#{::Liquid::QuotedFragment}+)?/
14
+
15
+ ########################################
16
+ ########################################
17
+
18
+ ## Parse Arguments ##
19
+ ## Define args here and pass to renderer as @variables ##
20
+ def initialize tag_name, markup, tokens
21
+ @tag = tag_name
22
+ @markup = markup.split(", ")
23
+ super
24
+ end
25
+
26
+ ## Output
27
+ def render context
28
+ meta @tag, @markup
29
+ end
30
+
31
+ ########################################
32
+ ########################################
33
+
34
+ private
35
+
36
+ # Helpers
37
+ def helpers
38
+ @helpers ||= ApplicationController.helpers
39
+ end
40
+
41
+ # Meta
42
+ # => Main meta method
43
+ # => tag is for self-enclosed tags (<meta> etc)
44
+ def meta type, *args
45
+ options = args.join(', ')
46
+
47
+ # Return Values
48
+ case type.to_sym
49
+ when :js, :javascript, :javascripts, :script, :scripts
50
+ helpers.javascript_include_tag *args
51
+ when :css, :stylesheet, :stylesheets
52
+ helpers.stylesheet_link_tag *args
53
+ when :title
54
+ helpers.content_tag :title, options
55
+ when :favicon
56
+ helpers.favicon_link_tag "icons/favicon.ico"
57
+ when :csrf
58
+ #helpers.csrf_meta_tags
59
+ else
60
+ helpers.tag :meta, name: type, content: options
61
+ end
62
+ end
63
+
64
+ ########################################
65
+ ########################################
66
+
67
+ # Robots
68
+ # => http://noarchive.net/meta/
69
+ def robots *args
70
+
71
+ # => Inputs
72
+ # => No input = all
73
+ # => If true and false are present, only true is passed
74
+ options = args.extract_options! # => Don't need defaults
75
+
76
+ # => Results
77
+ results = Array.new(2)
78
+ # No options / args = "index, follow"
79
+ # First check for one of the following :index, index: true, noindex: false == "index"
80
+ # Second check for one of the following :follow, follow: true, nofollow: false == "follow"
81
+ # Third check for one of the following :noindex, noindex: true == "noindex"
82
+ # Forth check for one of the following :nofollow, nofollow: true == "nofollow"
83
+ results[0] = "index" if options[:index] || args.include?(:index) || options[:noindex] == false || (options.empty? && args.empty?)
84
+ results[1] = "follow" if options[:follow] || args.include?(:follow) || options[:nofollow] == false || (options.empty? && args.empty?)
85
+ results[0] = "noindex" if (options[:noindex] || args.include?(:noindex) || options[:index] == false) && (!args.include?(:index))
86
+ results[1] = "nofollow" if (options[:nofollow] || args.include?(:nofollow) || options[:follow] == false) && (!args.include?(:follow))
87
+
88
+ results.delete_at(0) if (options[:index] == false) && (options[:index] != true || !args.include?(:index))
89
+ results.delete_at(1) if (options[:follow] == false) && (options[:follow] != true || !args.include?(:follow))
90
+
91
+ # => Return
92
+ # => Options only accepts actual content (array)
93
+ meta :robots, results.compact.join(",") if results.any?
94
+ end
95
+
96
+ # Favicon
97
+ # => https://github.com/audreyr/favicon-cheat-sheet
98
+ # => http://iconhandbook.co.uk/reference/chart/favicons/
99
+ def favicon img="icons/favicon.ico", *args
100
+
101
+ # => Accepts all styles of icon
102
+ defaults = { "apple-touch-icon" => [57,60,72,76,114,120,144,152,167,180], "icon" => [16,32] }
103
+ options = args.extract_options!.merge!(defaults) { |key, v1, v2| v1 }
104
+
105
+ case options
106
+ when :all
107
+
108
+ when true
109
+ else
110
+ meta :favicon, "https://www.frontlineutilities.co.uk/favicon.ico"
111
+ end
112
+ end
113
+
114
+ ########################################
115
+ ########################################
116
+
117
+ end
118
+
119
+ ###################################################
120
+ ###################################################
@@ -0,0 +1,28 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+
3
+ # => Address
4
+ # => http://stackoverflow.com/a/8106387/1143732
5
+ @@address = Mail::Address.new Rails.application.secrets.app[:email]
6
+ @@address.display_name = Rails.application.secrets.app[:domain]
7
+
8
+ # => Default
9
+ # => http://stackoverflow.com/a/18579046/1143732
10
+ default from: @@address.format, template_path: "mailers"
11
+
12
+ # Layout (app/views/layouts)
13
+ layout "mailers/layouts/mailer"
14
+
15
+ ##########################################################
16
+ ##########################################################
17
+
18
+ # For Admin "seeds" notification
19
+ def new_user user
20
+ @user = user
21
+ mail to: @@address
22
+ puts "User details sent to → #{@@address}"
23
+ end
24
+
25
+ ##########################################################
26
+ ##########################################################
27
+
28
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,95 @@
1
+ class Asset < ApplicationRecord
2
+
3
+ ####################################################################
4
+ ####################################################################
5
+
6
+ # Source - http://rails-bestpractices.com/posts/2010/08/18/use-sti-and-polymorphic-model-for-multiple-uploads/
7
+ # Need to find a way to remove the model name from the mix (IE "current_user.avatar.attachment.url" should be "current_user.avatar.url")
8
+ ##########################################
9
+ ##########################################
10
+
11
+ # => Associations
12
+ ##################
13
+ belongs_to :assetable, polymorphic: true
14
+
15
+ # => CkEditor
16
+ ##################
17
+ if defined? Ckeditor
18
+ include Ckeditor::Orm::ActiveRecord::AssetBase
19
+ include Ckeditor::Backend::Paperclip
20
+ end
21
+
22
+ # => Table
23
+ # => Required for CKEditor
24
+ ##################
25
+ self.table_name = "assets"
26
+
27
+ # => Paperclip
28
+ ##################
29
+ has_attached_file FL::FILE
30
+ validates_attachment FL::FILE, presence: true, content_type: { content_type: /\Aimage\/.*\z/, message: "%{value}" }, size: { in: 0..3.megabytes }
31
+
32
+ # => Alias
33
+ ##################
34
+ alias_attribute :ref, :id
35
+
36
+ ##########################################
37
+ ##########################################
38
+
39
+ ###################
40
+ # Methods #
41
+ ###################
42
+
43
+ # => Before Create
44
+ # => https://github.com/thoughtbot/paperclip/wiki/Extracting-image-dimensions
45
+ # => https://github.com/galetahub/ckeditor/blob/master/lib/ckeditor/backend/paperclip.rb#L38 (implemented in CKEditor)
46
+ before_create -> { %i(width height).each {|style| self[style] = geometry.send(style)} }, if: Proc.new { |i| i.image? and i.has_dimensions? }
47
+
48
+ # => Errors Fix
49
+ # => https://github.com/thoughtbot/paperclip/pull/1554#issuecomment-200666161
50
+ after_validation {|a| a.errors.delete(FL::FILE)}
51
+
52
+ ##########################################
53
+ ##########################################
54
+
55
+ # => URL
56
+ ##################
57
+ def url *args
58
+ data.url *args
59
+ end
60
+
61
+ # => CKEditor
62
+ ##################
63
+ def url_content
64
+ url(:medium)
65
+ end
66
+
67
+ # => Image?
68
+ ##################
69
+ def image?
70
+ %r(\Aimage\/.*\Z) =~ data_content_type
71
+ end
72
+
73
+ # => Dimensions
74
+ ##################
75
+ def has_dimensions?
76
+ respond_to?(:width) && respond_to?(:height)
77
+ end
78
+
79
+ ##########################################
80
+ ##########################################
81
+
82
+ private
83
+
84
+ # => Geometry
85
+ # => https://github.com/galetahub/ckeditor/blob/master/lib/ckeditor/backend/paperclip.rb#L23
86
+ def geometry
87
+ @geometry ||= begin
88
+ file = data.respond_to?(:queued_for_write) ? data.queued_for_write[:original] : data.to_file
89
+ ::Paperclip::Geometry.from_file(file)
90
+ end
91
+ end
92
+
93
+ ####################################################################
94
+
95
+ end