brightcontent-attachments 2.0.33 → 2.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 +1 -0
- data/app/assets/javascripts/brightcontent/attachments.js.coffee +42 -0
- data/app/assets/stylesheets/brightcontent/attachments.css.scss +3 -0
- data/app/controllers/brightcontent/attachments_controller.rb +9 -6
- data/app/models/brightcontent/attachment.rb +17 -1
- data/app/views/brightcontent/attachments/_attachment.html.erb +16 -10
- data/app/views/brightcontent/base/_form_field_attachments.html.erb +9 -11
- data/app/views/brightcontent/base/_list_field_attachments.html.erb +4 -0
- data/brightcontent-attachments.gemspec +1 -1
- data/config/locales/brightcontent_attachements.en.yml +8 -0
- data/config/locales/brightcontent_attachements.nl.yml +8 -0
- data/config/routes.rb +1 -1
- data/db/migrate/20140203140819_add_position_to_attachments.rb +5 -0
- data/lib/brightcontent/attachments/attachable.rb +16 -0
- data/lib/brightcontent/attachments/engine.rb +1 -1
- data/lib/brightcontent/attachments/model_extensions.rb +16 -0
- data/lib/brightcontent/attachments.rb +6 -2
- data/lib/generators/brightcontent/attachments/install_generator.rb +0 -3
- data/script/rails +2 -2
- data/spec/dummy/config/application.rb +2 -6
- data/spec/dummy/config/environments/development.rb +1 -10
- data/spec/dummy/config/environments/production.rb +0 -4
- data/spec/dummy/config/environments/test.rb +1 -6
- data/spec/dummy/config/initializers/secret_token.rb +1 -1
- data/spec/dummy/db/migrate/20121206121725_create_brightcontent_admin_users.rb +1 -1
- data/spec/dummy/db/schema.rb +14 -13
- data/spec/features/attachments_spec.rb +5 -6
- data/spec/models/brightcontent/attachable_spec.rb +10 -8
- data/spec/models/brightcontent/attachment_spec.rb +19 -0
- data/vendor/assets/javascripts/spin.js +353 -0
- metadata +33 -28
- data/app/assets/javascripts/brightcontent/attachments.js +0 -14
- data/app/helpers/brightcontent/attachments_helper.rb +0 -4
- data/lib/brightcontent/attachable.rb +0 -15
- data/lib/brightcontent/attachment_model_extensions.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fe1f577211b1bff0afc4b534bcea4542074de68
|
4
|
+
data.tar.gz: 325702f3a132bf2655a27b0bc013699b191e4927
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66247189162509cd49e45c686ae5ad59a260053110da12da42bb3f5ce975fef2d97918d8f2b1f0079ba8881c06c87676a33944c200d1fced267d188cec991c54
|
7
|
+
data.tar.gz: 83d89ffac4c3f21c62f0818c7d73ad35e3cbe1f32fa0cac70c302e2972ee58b644e80f70594eaad9bb641160b8a7800004dca1ac369ca85e7197e682cf578298
|
data/.gitignore
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
#= require jquery-fileupload/basic
|
2
|
+
#= require spin
|
3
|
+
|
4
|
+
$ ->
|
5
|
+
request_url = $("#attachable_url").val()
|
6
|
+
|
7
|
+
spinner = new Spinner().spin()
|
8
|
+
$('#fileupload').fileupload
|
9
|
+
method: "PUT"
|
10
|
+
send: ->
|
11
|
+
spinner.spin $("#attachments-controls")[0]
|
12
|
+
$("#attachments *").attr disabled: true
|
13
|
+
$("#fileupload").attr disabled: true
|
14
|
+
$("#attachments-controls").css opacity: 0.5
|
15
|
+
|
16
|
+
done: (e, data) ->
|
17
|
+
$.get request_url, (attachments_view) ->
|
18
|
+
$('#attachments').html attachments_view
|
19
|
+
spinner.stop()
|
20
|
+
$("#fileupload").attr disabled: false
|
21
|
+
$("#attachments-controls").css opacity: 1
|
22
|
+
|
23
|
+
|
24
|
+
$("#attachments").on "click", ".delete", ->
|
25
|
+
el = $(this).parents(".attachment")
|
26
|
+
spinner.spin el[0]
|
27
|
+
el.css opacity: 0.5
|
28
|
+
el.find("*").attr disabled: true
|
29
|
+
$.ajax
|
30
|
+
method: "DELETE"
|
31
|
+
url: $(this).attr "href"
|
32
|
+
success: -> el.remove()
|
33
|
+
false
|
34
|
+
|
35
|
+
$("#attachments").sortable
|
36
|
+
axis: "y"
|
37
|
+
cancel: "input,textarea,button,select,option,a"
|
38
|
+
distance: 5
|
39
|
+
update: ->
|
40
|
+
$.post "#{request_url}/reposition", positions: ($("#attachments > *").map -> $(this).data "attachment-id").toArray()
|
41
|
+
|
42
|
+
$("#attachments").disableSelection()
|
@@ -2,9 +2,8 @@ require_dependency "brightcontent/application_controller"
|
|
2
2
|
|
3
3
|
module Brightcontent
|
4
4
|
class AttachmentsController < ApplicationController
|
5
|
-
|
6
5
|
def show
|
7
|
-
@attachments = Attachment.
|
6
|
+
@attachments = Attachment.for_attachable(params[:type], params[:id])
|
8
7
|
render layout: false
|
9
8
|
end
|
10
9
|
|
@@ -18,15 +17,19 @@ module Brightcontent
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def destroy
|
21
|
-
|
22
|
-
|
20
|
+
Attachment.destroy params[:id]
|
21
|
+
head :no_content
|
22
|
+
end
|
23
|
+
|
24
|
+
def reposition
|
25
|
+
Attachment.for_attachable(params[:type], params[:id]).reposition! params[:positions]
|
26
|
+
head :no_content
|
23
27
|
end
|
24
28
|
|
25
29
|
private
|
26
30
|
|
27
31
|
def attachment_params
|
28
|
-
params.permit(:attachable_id, :attachable_type, :asset)
|
32
|
+
params.require(:attachment).permit(:attachable_id, :attachable_type, :asset)
|
29
33
|
end
|
30
|
-
|
31
34
|
end
|
32
35
|
end
|
@@ -3,13 +3,26 @@ module Brightcontent
|
|
3
3
|
belongs_to :attachable, polymorphic: true, :inverse_of => :attachments
|
4
4
|
has_attached_file :asset, :styles => lambda {|attachment| attachment.instance.attachment_styles }
|
5
5
|
before_post_process :resize_images
|
6
|
+
before_create :set_position
|
6
7
|
|
7
|
-
default_scope order("id")
|
8
|
+
default_scope { order("position, id") }
|
9
|
+
scope :for_attachable, -> type, id { where(attachable_type: type.classify, attachable_id: id) }
|
8
10
|
|
9
11
|
delegate :url, to: :asset
|
10
12
|
|
13
|
+
validates_attachment_content_type :asset, content_type: Brightcontent.attachment_content_types
|
14
|
+
validates :attachable, presence: true
|
11
15
|
validates :asset, attachment_presence: true
|
12
16
|
|
17
|
+
def self.reposition!(positions)
|
18
|
+
positions.map! &:to_i
|
19
|
+
transaction do
|
20
|
+
all.each do |attachment|
|
21
|
+
attachment.update_column :position, positions.index(attachment.id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
13
26
|
def attachment_styles
|
14
27
|
default_attachment_styles.merge(user_defined_styles)
|
15
28
|
end
|
@@ -34,5 +47,8 @@ module Brightcontent
|
|
34
47
|
return false unless image?
|
35
48
|
end
|
36
49
|
|
50
|
+
def set_position
|
51
|
+
self.position ||= self.class.for_attachable(attachable_type, attachable_id).maximum(:position).to_i + 1
|
52
|
+
end
|
37
53
|
end
|
38
54
|
end
|
@@ -1,10 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<div class="
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
<%
|
1
|
+
<li class="list-group-item attachment" data-attachment-id="<%= attachment.id %>">
|
2
|
+
<div class="media">
|
3
|
+
<% if attachment.image? %>
|
4
|
+
<%= image_tag attachment.url(:brightcontent), class: "media-object pull-left" %>
|
5
|
+
<% end %>
|
6
|
+
<div class="media-body">
|
7
|
+
<h4 class="attachment-file media-heading"><%= attachment.asset_file_name %></h4>
|
8
|
+
<% if attachment.image? %>
|
9
|
+
<%= link_to "Insert", nil, class: "insert insert_image btn btn-primary btn-xs", data: { insert_image: attachment.url(:main) } %>
|
10
|
+
<% else %>
|
11
|
+
<%= link_to "Insert", nil, class: "insert insert_link btn btn-primary btn-xs", data: { insert_url: attachment.url(:original), insert_name: attachment.asset_file_name } %>
|
12
|
+
<% end %>
|
13
|
+
<%= link_to "Delete", destroy_attachment_path(attachment.id), class: "delete btn btn-danger btn-xs", method: "delete" %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</li>
|
@@ -1,18 +1,16 @@
|
|
1
|
-
<div class="control-group
|
2
|
-
<label class="
|
3
|
-
<div class="controls">
|
1
|
+
<div class="control-group">
|
2
|
+
<label class="control-label"><%=Brightcontent::Attachment.model_name.human.pluralize%></label>
|
3
|
+
<div class="controls" id="attachments-controls">
|
4
4
|
<% if item.persisted? %>
|
5
|
-
<
|
5
|
+
<ul class="media-list" id="attachments">
|
6
6
|
<%= render item.attachments %>
|
7
|
-
</
|
8
|
-
|
9
|
-
|
10
|
-
<%= hidden_field_tag "
|
11
|
-
<%= hidden_field_tag "attachable_type", item.class.to_s %>
|
7
|
+
</ul>
|
8
|
+
<input id="fileupload" type="file" name="attachment[asset]" data-url="<%= new_attachment_path %>" class="form-control" multiple>
|
9
|
+
<%= hidden_field_tag "attachment[attachable_id]", item.id %>
|
10
|
+
<%= hidden_field_tag "attachment[attachable_type]", item.class.to_s %>
|
12
11
|
<%= hidden_field_tag "attachable_url", attachments_path(item.class.to_s, item.id) %>
|
13
|
-
|
14
12
|
<% else %>
|
15
|
-
|
13
|
+
<p class="form-control-static"><%= t('brightcontent.save_first')%></p>
|
16
14
|
<% end %>
|
17
15
|
</div>
|
18
16
|
</div>
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
|
18
18
|
s.add_dependency "brightcontent-core", version
|
19
|
-
s.add_dependency "paperclip"
|
19
|
+
s.add_dependency "paperclip", ">= 3.0.0"
|
20
20
|
s.add_dependency "jquery-fileupload-rails"
|
21
21
|
|
22
22
|
s.add_development_dependency "sqlite3"
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Brightcontent::Engine.routes.draw do
|
2
|
-
# TODO: put instead of create
|
3
2
|
get 'attachments/:type/:id' => 'attachments#show', as: :attachments
|
3
|
+
post 'attachments/:type/:id/reposition' => 'attachments#reposition'
|
4
4
|
put 'attachments' => 'attachments#create', as: :new_attachment
|
5
5
|
delete 'attachments/:id' => 'attachments#destroy', as: :destroy_attachment
|
6
6
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Brightcontent
|
2
|
+
module Attachments
|
3
|
+
module Attachable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
add_brightcontent_column :attachments
|
8
|
+
has_many :attachments, as: :attachable, dependent: :destroy, class_name: Brightcontent::Attachment, inverse_of: :attachable
|
9
|
+
end
|
10
|
+
|
11
|
+
def attachment
|
12
|
+
attachments.first
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Brightcontent
|
2
|
+
module Attachments
|
3
|
+
module ModelExtensions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
attr_reader :attachment_styles
|
8
|
+
|
9
|
+
def has_attached_files(styles)
|
10
|
+
include ::Brightcontent::Attachments::Attachable
|
11
|
+
@attachment_styles = styles
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,9 +5,13 @@ require "jquery-fileupload-rails"
|
|
5
5
|
require "brightcontent/attachments/engine"
|
6
6
|
|
7
7
|
module Brightcontent
|
8
|
-
|
9
|
-
|
8
|
+
register_extension 'attachments'
|
9
|
+
|
10
|
+
mattr_reader :attachment_content_types
|
11
|
+
@@attachment_content_types = [/\Aimage/, "application/pdf"]
|
10
12
|
|
11
13
|
module Attachments
|
14
|
+
autoload :Attachable, 'brightcontent/attachments/attachable'
|
15
|
+
autoload :ModelExtensions, 'brightcontent/attachments/model_extensions'
|
12
16
|
end
|
13
17
|
end
|
@@ -2,13 +2,10 @@ module Brightcontent
|
|
2
2
|
module Attachments
|
3
3
|
module Generators
|
4
4
|
class InstallGenerator < Rails::Generators::Base
|
5
|
-
|
6
5
|
desc "Install migrations for Brightcontent Attachments"
|
7
|
-
|
8
6
|
def copy_migrations
|
9
7
|
rake "brightcontent_attachments_engine:install:migrations"
|
10
8
|
end
|
11
|
-
|
12
9
|
end
|
13
10
|
end
|
14
11
|
end
|
data/script/rails
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
3
|
|
4
|
-
ENGINE_ROOT = File.expand_path('
|
5
|
-
ENGINE_PATH = File.expand_path('
|
4
|
+
ENGINE_ROOT = File.expand_path('../../../core', __FILE__)
|
5
|
+
ENGINE_PATH = File.expand_path('../../../core/lib/brightcontent/engine', __FILE__)
|
6
6
|
|
7
7
|
require 'rails/all'
|
8
8
|
require 'rails/engine/commands'
|
@@ -43,15 +43,11 @@ module Dummy
|
|
43
43
|
# like if you have constraints or database-specific column types
|
44
44
|
# config.active_record.schema_format = :sql
|
45
45
|
|
46
|
-
# Enforce whitelist mode for mass assignment.
|
47
|
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
48
|
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
49
|
-
# parameters by using an attr_accessible or attr_protected declaration.
|
50
|
-
config.active_record.whitelist_attributes = false
|
51
|
-
|
52
46
|
# Enable the asset pipeline
|
53
47
|
config.assets.enabled = true
|
54
48
|
|
49
|
+
# config.i18n.enforce_available_locales = true
|
50
|
+
|
55
51
|
# Version of your assets, change this if you want to expire all your assets
|
56
52
|
config.assets.version = '1.0'
|
57
53
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
Dummy::Application.configure do
|
2
2
|
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
config.eager_load = false
|
3
4
|
|
4
5
|
# In the development environment your application's code is reloaded on
|
5
6
|
# every request. This slows down response time but is perfect for development
|
6
7
|
# since you don't have to restart the web server when you make code changes.
|
7
8
|
config.cache_classes = false
|
8
9
|
|
9
|
-
# Log error messages when you accidentally call methods on nil.
|
10
|
-
config.whiny_nils = true
|
11
|
-
|
12
10
|
# Show full error reports and disable caching
|
13
11
|
config.consider_all_requests_local = true
|
14
12
|
config.action_controller.perform_caching = false
|
@@ -22,13 +20,6 @@ Dummy::Application.configure do
|
|
22
20
|
# Only use best-standards-support built into browsers
|
23
21
|
config.action_dispatch.best_standards_support = :builtin
|
24
22
|
|
25
|
-
# Raise exception on mass assignment protection for Active Record models
|
26
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
27
|
-
|
28
|
-
# Log the query plan for queries taking more than this (works
|
29
|
-
# with SQLite, MySQL, and PostgreSQL)
|
30
|
-
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
31
|
-
|
32
23
|
# Do not compress assets
|
33
24
|
config.assets.compress = false
|
34
25
|
|
@@ -60,8 +60,4 @@ Dummy::Application.configure do
|
|
60
60
|
|
61
61
|
# Send deprecation notices to registered listeners
|
62
62
|
config.active_support.deprecation = :notify
|
63
|
-
|
64
|
-
# Log the query plan for queries taking more than this (works
|
65
|
-
# with SQLite, MySQL, and PostgreSQL)
|
66
|
-
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
67
63
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
Dummy::Application.configure do
|
2
2
|
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
config.eager_load = false
|
3
4
|
|
4
5
|
# The test environment is used exclusively to run your application's
|
5
6
|
# test suite. You never need to work with it otherwise. Remember that
|
@@ -11,9 +12,6 @@ Dummy::Application.configure do
|
|
11
12
|
config.serve_static_assets = true
|
12
13
|
config.static_cache_control = "public, max-age=3600"
|
13
14
|
|
14
|
-
# Log error messages when you accidentally call methods on nil
|
15
|
-
config.whiny_nils = true
|
16
|
-
|
17
15
|
# Show full error reports and disable caching
|
18
16
|
config.consider_all_requests_local = true
|
19
17
|
config.action_controller.perform_caching = false
|
@@ -29,9 +27,6 @@ Dummy::Application.configure do
|
|
29
27
|
# ActionMailer::Base.deliveries array.
|
30
28
|
config.action_mailer.delivery_method = :test
|
31
29
|
|
32
|
-
# Raise exception on mass assignment protection for Active Record models
|
33
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
34
|
-
|
35
30
|
# Print deprecation notices to the stderr
|
36
31
|
config.active_support.deprecation = :stderr
|
37
32
|
end
|
@@ -4,4 +4,4 @@
|
|
4
4
|
# If you change this key, all old signed cookies will become invalid!
|
5
5
|
# Make sure the secret is at least 30 characters and all random,
|
6
6
|
# no regular words or you'll be exposed to dictionary attacks.
|
7
|
-
Dummy::Application.config.
|
7
|
+
Dummy::Application.config.secret_key_base = '1582af16879d84e4319aa02ea51964c7c27576e6468838ea1bcadf1286623d44e9117613a747386fde1bc2253a9a49c291a2c100fec64ae5c2cc5c75efa553ef'
|
@@ -7,6 +7,6 @@ class CreateBrightcontentAdminUsers < ActiveRecord::Migration
|
|
7
7
|
t.timestamps
|
8
8
|
end
|
9
9
|
|
10
|
-
Brightcontent::AdminUser.create!(:email => 'admin@example.com', :password => 'password')
|
10
|
+
Brightcontent::AdminUser.create!(:email => 'admin@example.com', :password => 'password', :password_confirmation => 'password')
|
11
11
|
end
|
12
12
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -9,36 +9,37 @@
|
|
9
9
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
10
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
11
|
#
|
12
|
-
# It's strongly recommended
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:
|
14
|
+
ActiveRecord::Schema.define(version: 20140203140819) do
|
15
15
|
|
16
|
-
create_table "blogs", :
|
16
|
+
create_table "blogs", force: true do |t|
|
17
17
|
t.string "name"
|
18
18
|
t.text "body"
|
19
|
-
t.datetime "created_at", :
|
20
|
-
t.datetime "updated_at", :
|
19
|
+
t.datetime "created_at", null: false
|
20
|
+
t.datetime "updated_at", null: false
|
21
21
|
end
|
22
22
|
|
23
|
-
create_table "brightcontent_admin_users", :
|
23
|
+
create_table "brightcontent_admin_users", force: true do |t|
|
24
24
|
t.string "email"
|
25
25
|
t.string "password_digest"
|
26
|
-
t.datetime "created_at", :
|
27
|
-
t.datetime "updated_at", :
|
26
|
+
t.datetime "created_at", null: false
|
27
|
+
t.datetime "updated_at", null: false
|
28
28
|
end
|
29
29
|
|
30
|
-
create_table "brightcontent_attachments", :
|
30
|
+
create_table "brightcontent_attachments", force: true do |t|
|
31
31
|
t.integer "attachable_id"
|
32
32
|
t.string "attachable_type"
|
33
33
|
t.string "asset_file_name"
|
34
34
|
t.string "asset_content_type"
|
35
35
|
t.integer "asset_file_size"
|
36
36
|
t.datetime "asset_updated_at"
|
37
|
-
t.datetime "created_at", :
|
38
|
-
t.datetime "updated_at", :
|
37
|
+
t.datetime "created_at", null: false
|
38
|
+
t.datetime "updated_at", null: false
|
39
|
+
t.integer "position"
|
39
40
|
end
|
40
41
|
|
41
|
-
add_index "brightcontent_attachments", ["attachable_id"], :
|
42
|
-
add_index "brightcontent_attachments", ["attachable_type"], :
|
42
|
+
add_index "brightcontent_attachments", ["attachable_id"], name: "index_brightcontent_attachments_on_attachable_id"
|
43
|
+
add_index "brightcontent_attachments", ["attachable_type"], name: "index_brightcontent_attachments_on_attachable_type"
|
43
44
|
|
44
45
|
end
|
@@ -7,7 +7,7 @@ feature "Attachments" do
|
|
7
7
|
|
8
8
|
scenario "show message if item is not saved" do
|
9
9
|
click_link "Blogs"
|
10
|
-
click_link "Create new
|
10
|
+
click_link "Create new blog"
|
11
11
|
page.should have_content "First save to enable uploads"
|
12
12
|
end
|
13
13
|
|
@@ -21,21 +21,20 @@ feature "Attachments" do
|
|
21
21
|
context "with image" do
|
22
22
|
background do
|
23
23
|
blog = create(:blog)
|
24
|
-
@attachment =
|
25
|
-
blog.attachments << @attachment
|
24
|
+
@attachment = blog.attachments.create!(:asset => Rails.root.join("public/rails.png").open)
|
26
25
|
click_link "Blogs"
|
27
26
|
click_link "Edit"
|
28
27
|
end
|
29
28
|
|
30
29
|
scenario "shows images" do
|
31
|
-
page.should have_selector "#
|
30
|
+
page.should have_selector "[data-attachment-id=\"#{@attachment.id}\"]"
|
32
31
|
end
|
33
32
|
|
34
33
|
scenario "delete image" do
|
35
|
-
within "#
|
34
|
+
within "[data-attachment-id=\"#{@attachment.id}\"]" do
|
36
35
|
click_link "Delete"
|
37
36
|
end
|
38
|
-
page.should_not have_selector "#
|
37
|
+
page.should_not have_selector "[data-attachment-id=\"#{@attachment.id}\"]"
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Brightcontent
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Attachments
|
5
|
+
describe Attachable do
|
6
|
+
subject { Blog }
|
7
|
+
its(:brightcontent_columns) { should include "attachments" }
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
it "should have a has_many relation to attachments" do
|
10
|
+
Blog.reflect_on_association(:attachments).macro.should eq :has_many
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
it "should have .attachment method" do
|
14
|
+
Blog.new.should respond_to :attachment
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -15,5 +15,24 @@ module Brightcontent
|
|
15
15
|
its(:attachment_styles) { should == { test: "200x200", brightcontent: "100x100#", main: "200x200#" } }
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
describe ".reposition!" do
|
20
|
+
let!(:blog) { build_stubbed(:blog) }
|
21
|
+
let!(:attachment_1) { blog.attachments.create!(:asset => Rails.root.join("public/rails.png").open) }
|
22
|
+
let!(:attachment_2) { blog.attachments.create!(:asset => Rails.root.join("public/rails.png").open) }
|
23
|
+
let!(:attachment_3) { blog.attachments.create!(:asset => Rails.root.join("public/rails.png").open) }
|
24
|
+
|
25
|
+
it "reorders the attachments as specified" do
|
26
|
+
ids = [attachment_2.id, attachment_3.id, attachment_1.id]
|
27
|
+
Attachment.reposition! ids
|
28
|
+
blog.attachments.pluck(:id).should == ids
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets unspecified attachments' positions to nil" do
|
32
|
+
ids = [attachment_3.id, attachment_2.id]
|
33
|
+
Attachment.reposition! ids
|
34
|
+
attachment_1.reload.position.should be_nil
|
35
|
+
end
|
36
|
+
end
|
18
37
|
end
|
19
38
|
end
|
@@ -0,0 +1,353 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2011-2013 Felix Gnass
|
3
|
+
* Licensed under the MIT license
|
4
|
+
*/
|
5
|
+
(function(root, factory) {
|
6
|
+
|
7
|
+
/* CommonJS */
|
8
|
+
if (typeof exports == 'object') module.exports = factory()
|
9
|
+
|
10
|
+
/* AMD module */
|
11
|
+
else if (typeof define == 'function' && define.amd) define(factory)
|
12
|
+
|
13
|
+
/* Browser global */
|
14
|
+
else root.Spinner = factory()
|
15
|
+
}
|
16
|
+
(this, function() {
|
17
|
+
"use strict";
|
18
|
+
|
19
|
+
var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
|
20
|
+
, animations = {} /* Animation rules keyed by their name */
|
21
|
+
, useCssAnimations /* Whether to use CSS animations or setTimeout */
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Utility function to create elements. If no tag name is given,
|
25
|
+
* a DIV is created. Optionally properties can be passed.
|
26
|
+
*/
|
27
|
+
function createEl(tag, prop) {
|
28
|
+
var el = document.createElement(tag || 'div')
|
29
|
+
, n
|
30
|
+
|
31
|
+
for(n in prop) el[n] = prop[n]
|
32
|
+
return el
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Appends children and returns the parent.
|
37
|
+
*/
|
38
|
+
function ins(parent /* child1, child2, ...*/) {
|
39
|
+
for (var i=1, n=arguments.length; i<n; i++)
|
40
|
+
parent.appendChild(arguments[i])
|
41
|
+
|
42
|
+
return parent
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Insert a new stylesheet to hold the @keyframe or VML rules.
|
47
|
+
*/
|
48
|
+
var sheet = (function() {
|
49
|
+
var el = createEl('style', {type : 'text/css'})
|
50
|
+
ins(document.getElementsByTagName('head')[0], el)
|
51
|
+
return el.sheet || el.styleSheet
|
52
|
+
}())
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Creates an opacity keyframe animation rule and returns its name.
|
56
|
+
* Since most mobile Webkits have timing issues with animation-delay,
|
57
|
+
* we create separate rules for each line/segment.
|
58
|
+
*/
|
59
|
+
function addAnimation(alpha, trail, i, lines) {
|
60
|
+
var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
|
61
|
+
, start = 0.01 + i/lines * 100
|
62
|
+
, z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
|
63
|
+
, prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
|
64
|
+
, pre = prefix && '-' + prefix + '-' || ''
|
65
|
+
|
66
|
+
if (!animations[name]) {
|
67
|
+
sheet.insertRule(
|
68
|
+
'@' + pre + 'keyframes ' + name + '{' +
|
69
|
+
'0%{opacity:' + z + '}' +
|
70
|
+
start + '%{opacity:' + alpha + '}' +
|
71
|
+
(start+0.01) + '%{opacity:1}' +
|
72
|
+
(start+trail) % 100 + '%{opacity:' + alpha + '}' +
|
73
|
+
'100%{opacity:' + z + '}' +
|
74
|
+
'}', sheet.cssRules.length)
|
75
|
+
|
76
|
+
animations[name] = 1
|
77
|
+
}
|
78
|
+
|
79
|
+
return name
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Tries various vendor prefixes and returns the first supported property.
|
84
|
+
*/
|
85
|
+
function vendor(el, prop) {
|
86
|
+
var s = el.style
|
87
|
+
, pp
|
88
|
+
, i
|
89
|
+
|
90
|
+
prop = prop.charAt(0).toUpperCase() + prop.slice(1)
|
91
|
+
for(i=0; i<prefixes.length; i++) {
|
92
|
+
pp = prefixes[i]+prop
|
93
|
+
if(s[pp] !== undefined) return pp
|
94
|
+
}
|
95
|
+
if(s[prop] !== undefined) return prop
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Sets multiple style properties at once.
|
100
|
+
*/
|
101
|
+
function css(el, prop) {
|
102
|
+
for (var n in prop)
|
103
|
+
el.style[vendor(el, n)||n] = prop[n]
|
104
|
+
|
105
|
+
return el
|
106
|
+
}
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Fills in default values.
|
110
|
+
*/
|
111
|
+
function merge(obj) {
|
112
|
+
for (var i=1; i < arguments.length; i++) {
|
113
|
+
var def = arguments[i]
|
114
|
+
for (var n in def)
|
115
|
+
if (obj[n] === undefined) obj[n] = def[n]
|
116
|
+
}
|
117
|
+
return obj
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Returns the absolute page-offset of the given element.
|
122
|
+
*/
|
123
|
+
function pos(el) {
|
124
|
+
var o = { x:el.offsetLeft, y:el.offsetTop }
|
125
|
+
while((el = el.offsetParent))
|
126
|
+
o.x+=el.offsetLeft, o.y+=el.offsetTop
|
127
|
+
|
128
|
+
return o
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Returns the line color from the given string or array.
|
133
|
+
*/
|
134
|
+
function getColor(color, idx) {
|
135
|
+
return typeof color == 'string' ? color : color[idx % color.length]
|
136
|
+
}
|
137
|
+
|
138
|
+
// Built-in defaults
|
139
|
+
|
140
|
+
var defaults = {
|
141
|
+
lines: 12, // The number of lines to draw
|
142
|
+
length: 7, // The length of each line
|
143
|
+
width: 5, // The line thickness
|
144
|
+
radius: 10, // The radius of the inner circle
|
145
|
+
rotate: 0, // Rotation offset
|
146
|
+
corners: 1, // Roundness (0..1)
|
147
|
+
color: '#000', // #rgb or #rrggbb
|
148
|
+
direction: 1, // 1: clockwise, -1: counterclockwise
|
149
|
+
speed: 1, // Rounds per second
|
150
|
+
trail: 100, // Afterglow percentage
|
151
|
+
opacity: 1/4, // Opacity of the lines
|
152
|
+
fps: 20, // Frames per second when using setTimeout()
|
153
|
+
zIndex: 2e9, // Use a high z-index by default
|
154
|
+
className: 'spinner', // CSS class to assign to the element
|
155
|
+
top: 'auto', // center vertically
|
156
|
+
left: 'auto', // center horizontally
|
157
|
+
position: 'relative' // element position
|
158
|
+
}
|
159
|
+
|
160
|
+
/** The constructor */
|
161
|
+
function Spinner(o) {
|
162
|
+
if (typeof this == 'undefined') return new Spinner(o)
|
163
|
+
this.opts = merge(o || {}, Spinner.defaults, defaults)
|
164
|
+
}
|
165
|
+
|
166
|
+
// Global defaults that override the built-ins:
|
167
|
+
Spinner.defaults = {}
|
168
|
+
|
169
|
+
merge(Spinner.prototype, {
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Adds the spinner to the given target element. If this instance is already
|
173
|
+
* spinning, it is automatically removed from its previous target b calling
|
174
|
+
* stop() internally.
|
175
|
+
*/
|
176
|
+
spin: function(target) {
|
177
|
+
this.stop()
|
178
|
+
|
179
|
+
var self = this
|
180
|
+
, o = self.opts
|
181
|
+
, el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
|
182
|
+
, mid = o.radius+o.length+o.width
|
183
|
+
, ep // element position
|
184
|
+
, tp // target position
|
185
|
+
|
186
|
+
if (target) {
|
187
|
+
target.insertBefore(el, target.firstChild||null)
|
188
|
+
tp = pos(target)
|
189
|
+
ep = pos(el)
|
190
|
+
css(el, {
|
191
|
+
left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
|
192
|
+
top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
|
193
|
+
})
|
194
|
+
}
|
195
|
+
|
196
|
+
el.setAttribute('role', 'progressbar')
|
197
|
+
self.lines(el, self.opts)
|
198
|
+
|
199
|
+
if (!useCssAnimations) {
|
200
|
+
// No CSS animation support, use setTimeout() instead
|
201
|
+
var i = 0
|
202
|
+
, start = (o.lines - 1) * (1 - o.direction) / 2
|
203
|
+
, alpha
|
204
|
+
, fps = o.fps
|
205
|
+
, f = fps/o.speed
|
206
|
+
, ostep = (1-o.opacity) / (f*o.trail / 100)
|
207
|
+
, astep = f/o.lines
|
208
|
+
|
209
|
+
;(function anim() {
|
210
|
+
i++;
|
211
|
+
for (var j = 0; j < o.lines; j++) {
|
212
|
+
alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
|
213
|
+
|
214
|
+
self.opacity(el, j * o.direction + start, alpha, o)
|
215
|
+
}
|
216
|
+
self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
|
217
|
+
})()
|
218
|
+
}
|
219
|
+
return self
|
220
|
+
},
|
221
|
+
|
222
|
+
/**
|
223
|
+
* Stops and removes the Spinner.
|
224
|
+
*/
|
225
|
+
stop: function() {
|
226
|
+
var el = this.el
|
227
|
+
if (el) {
|
228
|
+
clearTimeout(this.timeout)
|
229
|
+
if (el.parentNode) el.parentNode.removeChild(el)
|
230
|
+
this.el = undefined
|
231
|
+
}
|
232
|
+
return this
|
233
|
+
},
|
234
|
+
|
235
|
+
/**
|
236
|
+
* Internal method that draws the individual lines. Will be overwritten
|
237
|
+
* in VML fallback mode below.
|
238
|
+
*/
|
239
|
+
lines: function(el, o) {
|
240
|
+
var i = 0
|
241
|
+
, start = (o.lines - 1) * (1 - o.direction) / 2
|
242
|
+
, seg
|
243
|
+
|
244
|
+
function fill(color, shadow) {
|
245
|
+
return css(createEl(), {
|
246
|
+
position: 'absolute',
|
247
|
+
width: (o.length+o.width) + 'px',
|
248
|
+
height: o.width + 'px',
|
249
|
+
background: color,
|
250
|
+
boxShadow: shadow,
|
251
|
+
transformOrigin: 'left',
|
252
|
+
transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
|
253
|
+
borderRadius: (o.corners * o.width>>1) + 'px'
|
254
|
+
})
|
255
|
+
}
|
256
|
+
|
257
|
+
for (; i < o.lines; i++) {
|
258
|
+
seg = css(createEl(), {
|
259
|
+
position: 'absolute',
|
260
|
+
top: 1+~(o.width/2) + 'px',
|
261
|
+
transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
|
262
|
+
opacity: o.opacity,
|
263
|
+
animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
|
264
|
+
})
|
265
|
+
|
266
|
+
if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
|
267
|
+
ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')))
|
268
|
+
}
|
269
|
+
return el
|
270
|
+
},
|
271
|
+
|
272
|
+
/**
|
273
|
+
* Internal method that adjusts the opacity of a single line.
|
274
|
+
* Will be overwritten in VML fallback mode below.
|
275
|
+
*/
|
276
|
+
opacity: function(el, i, val) {
|
277
|
+
if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
|
278
|
+
}
|
279
|
+
|
280
|
+
})
|
281
|
+
|
282
|
+
|
283
|
+
function initVML() {
|
284
|
+
|
285
|
+
/* Utility function to create a VML tag */
|
286
|
+
function vml(tag, attr) {
|
287
|
+
return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
|
288
|
+
}
|
289
|
+
|
290
|
+
// No CSS transforms but VML support, add a CSS rule for VML elements:
|
291
|
+
sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
|
292
|
+
|
293
|
+
Spinner.prototype.lines = function(el, o) {
|
294
|
+
var r = o.length+o.width
|
295
|
+
, s = 2*r
|
296
|
+
|
297
|
+
function grp() {
|
298
|
+
return css(
|
299
|
+
vml('group', {
|
300
|
+
coordsize: s + ' ' + s,
|
301
|
+
coordorigin: -r + ' ' + -r
|
302
|
+
}),
|
303
|
+
{ width: s, height: s }
|
304
|
+
)
|
305
|
+
}
|
306
|
+
|
307
|
+
var margin = -(o.width+o.length)*2 + 'px'
|
308
|
+
, g = css(grp(), {position: 'absolute', top: margin, left: margin})
|
309
|
+
, i
|
310
|
+
|
311
|
+
function seg(i, dx, filter) {
|
312
|
+
ins(g,
|
313
|
+
ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
|
314
|
+
ins(css(vml('roundrect', {arcsize: o.corners}), {
|
315
|
+
width: r,
|
316
|
+
height: o.width,
|
317
|
+
left: o.radius,
|
318
|
+
top: -o.width>>1,
|
319
|
+
filter: filter
|
320
|
+
}),
|
321
|
+
vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
|
322
|
+
vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
|
323
|
+
)
|
324
|
+
)
|
325
|
+
)
|
326
|
+
}
|
327
|
+
|
328
|
+
if (o.shadow)
|
329
|
+
for (i = 1; i <= o.lines; i++)
|
330
|
+
seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
|
331
|
+
|
332
|
+
for (i = 1; i <= o.lines; i++) seg(i)
|
333
|
+
return ins(el, g)
|
334
|
+
}
|
335
|
+
|
336
|
+
Spinner.prototype.opacity = function(el, i, val, o) {
|
337
|
+
var c = el.firstChild
|
338
|
+
o = o.shadow && o.lines || 0
|
339
|
+
if (c && i+o < c.childNodes.length) {
|
340
|
+
c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
|
341
|
+
if (c) c.opacity = val
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
|
347
|
+
|
348
|
+
if (!vendor(probe, 'transform') && probe.adj) initVML()
|
349
|
+
else useCssAnimations = vendor(probe, 'animation')
|
350
|
+
|
351
|
+
return Spinner
|
352
|
+
|
353
|
+
}));
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brightcontent-attachments
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Developers at Brightin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: brightcontent-core
|
@@ -16,110 +16,110 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.0
|
19
|
+
version: 2.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.0
|
26
|
+
version: 2.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: paperclip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: jquery-fileupload-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: sqlite3
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec-rails
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: capybara
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: launchy
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: factory_girl_rails
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
description: Separate attachment resource for brightcontent
|
@@ -128,26 +128,30 @@ executables: []
|
|
128
128
|
extensions: []
|
129
129
|
extra_rdoc_files: []
|
130
130
|
files:
|
131
|
-
- .gitignore
|
131
|
+
- ".gitignore"
|
132
132
|
- Gemfile
|
133
133
|
- README.md
|
134
134
|
- Rakefile
|
135
135
|
- app/assets/javascripts/brightcontent/.gitkeep
|
136
|
-
- app/assets/javascripts/brightcontent/attachments.js
|
136
|
+
- app/assets/javascripts/brightcontent/attachments.js.coffee
|
137
|
+
- app/assets/stylesheets/brightcontent/attachments.css.scss
|
137
138
|
- app/controllers/brightcontent/attachments_controller.rb
|
138
|
-
- app/helpers/brightcontent/attachments_helper.rb
|
139
139
|
- app/models/brightcontent/attachment.rb
|
140
140
|
- app/views/brightcontent/attachments/_attachment.html.erb
|
141
141
|
- app/views/brightcontent/attachments/show.html.erb
|
142
142
|
- app/views/brightcontent/base/_form_field_attachments.html.erb
|
143
|
+
- app/views/brightcontent/base/_list_field_attachments.html.erb
|
143
144
|
- brightcontent-attachments.gemspec
|
145
|
+
- config/locales/brightcontent_attachements.en.yml
|
146
|
+
- config/locales/brightcontent_attachements.nl.yml
|
144
147
|
- config/routes.rb
|
145
148
|
- db/migrate/20121222172513_create_attachments.rb
|
149
|
+
- db/migrate/20140203140819_add_position_to_attachments.rb
|
146
150
|
- lib/brightcontent-attachments.rb
|
147
|
-
- lib/brightcontent/attachable.rb
|
148
|
-
- lib/brightcontent/attachment_model_extensions.rb
|
149
151
|
- lib/brightcontent/attachments.rb
|
152
|
+
- lib/brightcontent/attachments/attachable.rb
|
150
153
|
- lib/brightcontent/attachments/engine.rb
|
154
|
+
- lib/brightcontent/attachments/model_extensions.rb
|
151
155
|
- lib/generators/brightcontent/attachments/install_generator.rb
|
152
156
|
- script/rails
|
153
157
|
- spec/dummy/README.rdoc
|
@@ -208,6 +212,7 @@ files:
|
|
208
212
|
- spec/models/brightcontent/attachment_spec.rb
|
209
213
|
- spec/spec_helper.rb
|
210
214
|
- spec/support/acceptance_helper.rb
|
215
|
+
- vendor/assets/javascripts/spin.js
|
211
216
|
homepage: http://brightin.nl
|
212
217
|
licenses: []
|
213
218
|
metadata: {}
|
@@ -217,17 +222,17 @@ require_paths:
|
|
217
222
|
- lib
|
218
223
|
required_ruby_version: !ruby/object:Gem::Requirement
|
219
224
|
requirements:
|
220
|
-
- -
|
225
|
+
- - ">="
|
221
226
|
- !ruby/object:Gem::Version
|
222
227
|
version: '0'
|
223
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
229
|
requirements:
|
225
|
-
- -
|
230
|
+
- - ">="
|
226
231
|
- !ruby/object:Gem::Version
|
227
232
|
version: '0'
|
228
233
|
requirements: []
|
229
234
|
rubyforge_project:
|
230
|
-
rubygems_version: 2.
|
235
|
+
rubygems_version: 2.2.2
|
231
236
|
signing_key:
|
232
237
|
specification_version: 4
|
233
238
|
summary: Assets resource for brightcontent
|
@@ -1,14 +0,0 @@
|
|
1
|
-
//= require jquery-fileupload/basic
|
2
|
-
|
3
|
-
$(function () {
|
4
|
-
|
5
|
-
var request_url = $("#attachable_url").val();
|
6
|
-
|
7
|
-
$('#fileupload').fileupload({
|
8
|
-
done: function (e, data) {
|
9
|
-
$.get(request_url, function(data) {
|
10
|
-
$('#attachments').html(data);
|
11
|
-
});
|
12
|
-
}
|
13
|
-
});
|
14
|
-
});
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Brightcontent
|
2
|
-
module Attachable
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
add_brightcontent_column :attachments
|
7
|
-
has_many :attachments, as: :attachable, dependent: :destroy, class_name: Brightcontent::Attachment, :inverse_of => :attachable
|
8
|
-
end
|
9
|
-
|
10
|
-
def attachment
|
11
|
-
attachments.first
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Brightcontent
|
2
|
-
module AttachmentModelExtensions
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
attr_reader :attachment_styles
|
7
|
-
def has_attached_files(styles)
|
8
|
-
include Brightcontent::Attachable
|
9
|
-
@attachment_styles = styles
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|