loft 0.1.5 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f204fc64713eb740598cd03d4cd32aa11313719
4
- data.tar.gz: 39d010891c3e501c7321690cdcfe81b4e4ba26f9
3
+ metadata.gz: 391b496e43ed6be6213e78ebaafd043f3e10cd61
4
+ data.tar.gz: 312c8ac2abbec5cfb6ee5038917d104b32f6fa3b
5
5
  SHA512:
6
- metadata.gz: 8bbe85ed20e0221a0d4776100bfa2a8648816b6ce960d5aeb590990fbcb2586ed29efdef9822c46f811b3a97fb5e6d2aa353e02c7273ecdb6691891e58fccbfc
7
- data.tar.gz: b612bcbf8a16792e2231b79e250be6ea4c6cf3bfee97c465fda6f8825317a65ed3fa862797747c1a25c5135fe1230aab3eb2130a4904bae35d9981ef7eaee6a1
6
+ metadata.gz: f57ee9453fc99a64b80551e2ca8b1311848bd203f4b2e8414d23d4f27b877376188b43b9cc05ef80b82efe7b760d1b6efa50eb5724fc1c74176c87edec2fb73a
7
+ data.tar.gz: 7d565f0e5e16f69889cf9caf6851cdba6614079965afe2d0f329b352cdce2798a4847b8fafb9c28cd4c7cfecd7064299ac713b04747df744c60ad7e11e39465c
data/.gitignore CHANGED
@@ -1,4 +1,2 @@
1
1
  *.gem
2
- .DS_Store
3
-
4
- node_modules/
2
+ .DS_Store
data/README.md CHANGED
@@ -14,8 +14,6 @@ Setup a new model for assets ```asset.rb```:
14
14
  ```ruby
15
15
  class Asset
16
16
  include Mongoid::Document
17
- include Mongoid::Timestamps
18
- include Mongoid::SerializableId
19
17
  include Mongoid::LoftAsset
20
18
  end
21
19
  ```
@@ -25,8 +23,8 @@ Add controller for asset model to make it accesible via CMS, e.g. ```app/control
25
23
  ```ruby
26
24
  class Admin::AssetsController < Admin::BaseController
27
25
  mongosteen
26
+
28
27
  has_scope :by_type
29
- json_config({ methods: [ :item_thumbnail, :created_ago ] })
30
28
  end
31
29
  ```
32
30
 
data/Rakefile CHANGED
@@ -1,3 +1 @@
1
- # encoding: utf-8
2
- require "rubygems"
3
- require "bundler"
1
+ require "bundler/gem_tasks"
@@ -3,8 +3,7 @@
3
3
  #= require loft/module
4
4
 
5
5
  #= require loft/redactor-loft
6
- #= require loft/input-loft-asset
7
- #= require loft/input-loft-image
6
+ #= require loft/inputs/loft-image
8
7
 
9
8
  # TODOs:
10
9
  # - refactor group remove action: delete a bunch first, then reload the page
@@ -61,8 +61,8 @@ class @LoftAssetItem extends Item
61
61
 
62
62
  # thumbnail for images
63
63
  if @object.type == 'image' && @object.grid_item_thumbnail != ''
64
- @$thumbnailSmall =$ "<img class='asset-thumbnail-small' src='#{ @object.item_thumbnail.small }' />"
65
- @$thumbnailMedium =$ "<img class='asset-thumbnail-medium' src='#{ @object.item_thumbnail.medium }' />"
64
+ @$thumbnailSmall =$ "<img class='asset-thumbnail-small' src='#{ @object._list_item_thumbnail.small }' />"
65
+ @$thumbnailMedium =$ "<img class='asset-thumbnail-medium' src='#{ @object._list_item_thumbnail.medium }' />"
66
66
  @$link.append @$thumbnailSmall
67
67
  @$link.append @$thumbnailMedium
68
68
 
@@ -89,8 +89,12 @@ class @LoftGroupActions
89
89
  object = @list.config.arrayStore.get(objectId)
90
90
  objects.push object
91
91
 
92
- @loft.onAcceptCallback(objects)
93
- @loft.closeModal()
92
+ if @loft.closeOnAccept
93
+ @loft.onAcceptCallback(objects)
94
+ @loft.closeModal()
95
+
96
+ else
97
+ @loft.onAcceptCallback(objects, => @loft.closeModal())
94
98
 
95
99
 
96
100
  _show: ->
@@ -22,8 +22,7 @@ class @InputLoftImage extends InputString
22
22
  @updateValue($(e.target).val())
23
23
 
24
24
  @_add_image()
25
- @_add_choose_button()
26
- @_add_remove_button()
25
+ @_add_actions()
27
26
  @_update_input_class()
28
27
 
29
28
 
@@ -33,9 +32,17 @@ class @InputLoftImage extends InputString
33
32
  @_update_image()
34
33
 
35
34
 
35
+ _add_actions: ->
36
+ @$actions =$ "<span class='input-actions'></span>"
37
+ @$label.append @$actions
38
+
39
+ @_add_choose_button()
40
+ @_add_remove_button()
41
+
42
+
36
43
  _add_choose_button: ->
37
- @$chooseBtn =$ "<a href='#' class='choose'></a><br/>"
38
- @$el.append @$chooseBtn
44
+ @$chooseBtn =$ "<a href='#' class='choose'></a>"
45
+ @$actions.append @$chooseBtn
39
46
 
40
47
  @_update_choose_button_title()
41
48
 
@@ -48,7 +55,7 @@ class @InputLoftImage extends InputString
48
55
 
49
56
  _add_remove_button: ->
50
57
  @$removeBtn =$ "<a href='#' class='remove'>Remove</a>"
51
- @$el.append @$removeBtn
58
+ @$actions.append @$removeBtn
52
59
 
53
60
  @$removeBtn.on 'click', (e) =>
54
61
  e.preventDefault()
@@ -63,7 +70,7 @@ class @InputLoftImage extends InputString
63
70
 
64
71
 
65
72
  _update_choose_button_title: ->
66
- title = if @value == '' then 'Choose or upload' else 'Choose other or upload'
73
+ title = if @value == '' then 'Choose or upload an image' else 'Choose other or upload'
67
74
  @$chooseBtn.html(title)
68
75
 
69
76
 
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # Public methods:
14
14
  # new Loft(title, resource, resourcePath, @arrayStoreClass, @arrayStoreConfig)
15
- # showModal(assetType, @selectMultipleAssets, @onAcceptCallback)
15
+ # showModal(assetType, @selectMultipleAssets, @onAcceptCallback, @closeOnAccept)
16
16
  # closeModal()
17
17
  #
18
18
  # -----------------------------------------------------------------------------
@@ -56,8 +56,8 @@ class @Loft
56
56
  @store = @module.nestedLists.loft_all.config.arrayStore
57
57
 
58
58
  # API method
59
- @module.showModal = (assetType, selectMultipleAssets, callback) =>
60
- @showModal(assetType, selectMultipleAssets, callback)
59
+ @module.showModal = (assetType, selectMultipleAssets, callback, closeOnAccept) =>
60
+ @showModal(assetType, selectMultipleAssets, callback, closeOnAccept)
61
61
  @selectMultipleAssets = true
62
62
 
63
63
  # modal close button
@@ -93,12 +93,10 @@ class @Loft
93
93
  $.extend(storeConfig, { urlParams: { by_type: assetType } })
94
94
 
95
95
  config =
96
- title: moduleName
97
- itemTitleField: 'name'
98
- itemSubtitleField: 'created_ago'
99
- showWithParent: true
100
- itemClass: LoftAssetItem
101
- arrayStore: new @arrayStoreClass(storeConfig)
96
+ title: moduleName
97
+ showWithParent: true
98
+ itemClass: LoftAssetItem
99
+ arrayStore: new @arrayStoreClass(storeConfig)
102
100
  onListInit: (list) => @_inititialize_list(list)
103
101
  onListShow: (list) => @_clear_assets_selection()
104
102
 
@@ -175,7 +173,7 @@ class @Loft
175
173
 
176
174
 
177
175
  # chr.modules.assets.showModal()
178
- showModal: (assetType='all', @selectMultipleAssets=false, @onAcceptCallback=$.noop) ->
176
+ showModal: (assetType='all', @selectMultipleAssets=false, @onAcceptCallback=$.noop, @closeOnAccept=true) ->
179
177
  # modal mode
180
178
  @module.$el.addClass('module-modal')
181
179
  # show module
@@ -0,0 +1,8 @@
1
+ .input-loft-image {
2
+ input { margin-bottom: .25em; }
3
+ .image img { max-height: 6em; margin: .25em .75em .25em 0; float: left; }
4
+ .remove { display: none; }
5
+
6
+ &.has-value { min-height: 11em; }
7
+ &.has-value .remove { display: inline; }
8
+ }
@@ -3,7 +3,7 @@
3
3
  // admin.scss (default)
4
4
  //
5
5
 
6
- @import "chr/form/input-loft-image";
6
+ @import "inputs/loft-image";
7
7
 
8
8
  // MIXINS
9
9
 
data/lib/loft/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Loft
2
- VERSION = "0.1.5"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -8,13 +8,16 @@ module Mongoid
8
8
  included do
9
9
 
10
10
  include Mongoid::Timestamps
11
- include Mongoid::SerializableId
12
11
  include Mongoid::Autoinc
13
12
  include Mongoid::Search
13
+
14
+ include Ants::Id
15
+
14
16
  include ActionView::Helpers::DateHelper
15
17
  include ActionView::Helpers::NumberHelper
16
18
 
17
- # attributes
19
+
20
+ ## Attributes
18
21
  field :name, default: ''
19
22
  field :filename, default: ''
20
23
  field :size, type: Integer
@@ -30,38 +33,44 @@ module Mongoid
30
33
  field :_number, type: Integer
31
34
  increments :_number
32
35
 
33
- # uploaders
36
+
37
+ ## Uploaders
34
38
  mount_uploader :file, AssetFileUploader
35
39
 
36
- # validations
40
+
41
+ ## Validations
37
42
  validates :file, presence: true
38
43
 
39
- # search
44
+
45
+ ## Search
40
46
  search_in :name, :filename
41
47
 
42
- # scopes
48
+
49
+ ## Scopes
43
50
  default_scope -> { desc(:created_at) }
44
51
  scope :by_type, -> asset_type { where(type: asset_type) }
45
52
 
46
- # indexes
53
+
54
+ ## Indexes
47
55
  index({ created_at: -1 })
48
56
 
49
- # callbacks
57
+
58
+ ## Callbacks
50
59
  before_save :update_asset_attributes
51
60
 
52
61
 
53
- # helpers
54
- def created_ago
55
- time_ago_in_words(self.created_at) + " ago"
62
+ ## Helpers
63
+ def _list_item_title
64
+ name
56
65
  end
57
66
 
58
67
 
59
- def content_type
60
- @content_type ||= file.content_type
68
+ def _list_item_subtitle
69
+ time_ago_in_words(self.created_at) + " ago"
61
70
  end
62
71
 
63
72
 
64
- def item_thumbnail
73
+ def _list_item_thumbnail
65
74
  if is_image?
66
75
  { medium: file._200x150_2x.url, small: file._40x40_2x.url }
67
76
  else
@@ -70,6 +79,11 @@ module Mongoid
70
79
  end
71
80
 
72
81
 
82
+ def content_type
83
+ @content_type ||= file.content_type
84
+ end
85
+
86
+
73
87
  def is_image?
74
88
  return false unless file?
75
89
  content_type.match(/image\//) ? true : false
@@ -82,6 +96,12 @@ module Mongoid
82
96
  end
83
97
 
84
98
 
99
+ def is_pdf?
100
+ return false unless file?
101
+ content_type.match(/pdf/) ? true : false
102
+ end
103
+
104
+
85
105
  def is_archive?
86
106
  return false unless file?
87
107
  # need to add more archive types: rar, gz, bz2, gzip
@@ -116,6 +136,7 @@ module Mongoid
116
136
  # asset types
117
137
  self.type = 'image' if self.is_image?
118
138
  self.type = 'text' if self.is_text?
139
+ self.type = 'text' if self.is_pdf?
119
140
  self.type = 'archive' if self.is_archive?
120
141
  self.type = 'audio' if self.is_audio?
121
142
  self.type = 'video' if self.is_video?
data/loft.gemspec CHANGED
@@ -21,13 +21,14 @@ to upload, manage and insert files into documents.
21
21
  s.files = `git ls-files`.split("\n")
22
22
  s.require_paths = ['lib']
23
23
 
24
- s.add_dependency("mongoid_search", ">= 0.3.1")
24
+ s.add_dependency("chr", ">= 0.4.0")
25
+ s.add_dependency("ants", ">= 0.2.0")
26
+ s.add_dependency("mongosteen", ">= 0.1.8")
25
27
  s.add_dependency("mongoid-autoinc", ">= 4.0.0")
26
28
  s.add_dependency("mini_magick", ">= 4.1.0")
27
29
  s.add_dependency("mongoid-grid_fs", ">= 2.1.0")
28
30
  s.add_dependency("carrierwave-mongoid", ">= 0.7.1")
29
- end
30
-
31
-
32
-
33
31
 
32
+ s.add_development_dependency "bundler", "~> 1.9"
33
+ s.add_development_dependency "rake", "~> 10.0"
34
+ end
metadata CHANGED
@@ -1,29 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Kravets
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-27 00:00:00.000000000 Z
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: mongoid_search
14
+ name: chr
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.1
19
+ version: 0.4.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: 0.3.1
26
+ version: 0.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: ants
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: mongosteen
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.8
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.8
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: mongoid-autoinc
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +108,34 @@ dependencies:
80
108
  - - ">="
81
109
  - !ruby/object:Gem::Version
82
110
  version: 0.7.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '10.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '10.0'
83
139
  description: |
84
140
  This plugin adds an assets library that provides an easy way
85
141
  to upload, manage and insert files into documents.
@@ -91,7 +147,6 @@ files:
91
147
  - ".gitignore"
92
148
  - CONTRIBUTING.md
93
149
  - Gemfile
94
- - Gruntfile.coffee
95
150
  - LICENSE.md
96
151
  - README.md
97
152
  - Rakefile
@@ -99,22 +154,18 @@ files:
99
154
  - app/assets/javascripts/loft.coffee
100
155
  - app/assets/javascripts/loft/asset-item.coffee
101
156
  - app/assets/javascripts/loft/group-actions.coffee
102
- - app/assets/javascripts/loft/input-loft-asset.coffee
103
- - app/assets/javascripts/loft/input-loft-image.coffee
157
+ - app/assets/javascripts/loft/inputs/loft-image.coffee
104
158
  - app/assets/javascripts/loft/module.coffee
105
159
  - app/assets/javascripts/loft/redactor-loft.coffee
106
- - app/assets/stylesheets/_loft.scss
107
- - app/assets/stylesheets/chr/form/_input-loft-image.scss
160
+ - app/assets/stylesheets/inputs/loft-image.scss
161
+ - app/assets/stylesheets/loft.scss
108
162
  - app/uploaders/asset_file_uploader.rb
109
- - bower.json
110
- - dist/loft.js
111
163
  - lib/concerns/asset_file_uploader.rb
112
164
  - lib/loft.rb
113
165
  - lib/loft/engine.rb
114
166
  - lib/loft/version.rb
115
167
  - lib/mongoid/loft_asset.rb
116
168
  - loft.gemspec
117
- - package.json
118
169
  homepage: http://slatestudio.com
119
170
  licenses:
120
171
  - MIT
@@ -135,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
186
  version: '0'
136
187
  requirements: []
137
188
  rubyforge_project: loft
138
- rubygems_version: 2.4.5
189
+ rubygems_version: 2.4.6
139
190
  signing_key:
140
191
  specification_version: 4
141
192
  summary: Media assets manager for Character CMS
data/Gruntfile.coffee DELETED
@@ -1,41 +0,0 @@
1
- module.exports = (grunt) ->
2
- # Project configuration
3
- grunt.initConfig
4
- pkg: grunt.file.readJSON('package.json')
5
- coffee:
6
- compileBare:
7
- options:
8
- bare: true
9
- files:
10
- 'build/loft.js': [
11
- # core
12
- 'app/assets/javascripts/loft/group-actions.coffee'
13
- 'app/assets/javascripts/loft/asset-item.coffee'
14
- 'app/assets/javascripts/loft/module.coffee'
15
- # redactor
16
- 'app/assets/javascripts/loft/redactor-loft.coffee'
17
- # inputs
18
- 'app/assets/javascripts/loft/input-loft-asset.coffee'
19
- 'app/assets/javascripts/loft/input-loft-image.coffee'
20
- ]
21
-
22
- concat:
23
- loft:
24
- src: [
25
- 'build/loft.js'
26
- ]
27
- dest: 'dist/loft.js'
28
-
29
- clean: [
30
- 'build'
31
- ]
32
-
33
- grunt.loadNpmTasks('grunt-contrib-coffee')
34
- grunt.loadNpmTasks('grunt-contrib-concat')
35
- grunt.loadNpmTasks('grunt-contrib-clean')
36
-
37
- grunt.registerTask('default', ['coffee', 'concat', 'clean'])
38
-
39
-
40
-
41
-
@@ -1,11 +0,0 @@
1
- # -----------------------------------------------------------------------------
2
- # Author: Alexander Kravets <alex@slatestudio.com>,
3
- # Slate Studio (http://www.slatestudio.com)
4
- #
5
- # Coding Guide:
6
- # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
- # -----------------------------------------------------------------------------
8
-
9
- # -----------------------------------------------------------------------------
10
- # INPUT LOFT ASSET
11
- # -----------------------------------------------------------------------------
@@ -1,11 +0,0 @@
1
- .input-loft-image {
2
- &.has-value { min-height: 11em; }
3
-
4
- input { margin-bottom: .25em; }
5
- .image img { max-height: 6em; margin: .25em .75em .25em 0; float: left; }
6
- .choose, .remove { color: $positiveColor; display: inline-block; }
7
-
8
- &.has-value .choose { margin-top: .25em; }
9
- &.has-value .remove { display: inline-block; }
10
- .remove { display: none; font-size: .8em; margin-top: .5em; }
11
- }
data/bower.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "name": "loft",
3
- "version": "0.1.5",
4
- "homepage": "https://github.com/slate-studio/loft",
5
- "authors": [
6
- "Slate Studio (http://www.slatestudio.com)"
7
- ],
8
- "license": "MIT",
9
- "description": "Media assets manager for Character CMS.",
10
- "main": "app/assets/stylesheets/_loft.scss, dist/loft.js, app/assets/images/loft/library@3x.png",
11
- "keywords": [
12
- "character",
13
- "cms",
14
- "gallery",
15
- "pugin",
16
- "images",
17
- "files"
18
- ],
19
- "ignore": [
20
- "**/.*",
21
- "lib",
22
- "docs",
23
- "chr.gemspec",
24
- "Gemfile",
25
- "Gemfile.lock",
26
- "Gruntfile.coffee",
27
- "package.json",
28
- "Rakefile"
29
- ],
30
- "repository": {
31
- "type": "git",
32
- "url": "https://github.com/slate-studio/loft.git"
33
- },
34
- "dependencies": {
35
- "bourbon": ">=4.0",
36
- "normalize-scss": ">=3.0"
37
- }
38
- }
data/dist/loft.js DELETED
@@ -1,603 +0,0 @@
1
- this.LoftGroupActions = (function() {
2
- function LoftGroupActions(list, loft) {
3
- this.list = list;
4
- this.loft = loft;
5
- this._render();
6
- this._bind_checkboxes();
7
- }
8
-
9
- LoftGroupActions.prototype._render = function() {
10
- this.$el = $("<div class='assets-group-actions' style='display:none;'></div>");
11
- this.list.$header.append(this.$el);
12
- this.$acceptBtn = $("<a href='#' class='accept'>Accept</a>");
13
- this.$acceptBtn.on('click', (function(_this) {
14
- return function(e) {
15
- e.preventDefault();
16
- return _this._accept_selected_items();
17
- };
18
- })(this));
19
- this.$el.append(this.$acceptBtn);
20
- this.$deleteBtn = $("<a href='#' class='delete'>Delete Selected</a>");
21
- this.$deleteBtn.on('click', (function(_this) {
22
- return function(e) {
23
- e.preventDefault();
24
- return _this._delete_selected_list_items();
25
- };
26
- })(this));
27
- this.$el.append(this.$deleteBtn);
28
- this.$unselectBtn = $("<a href='#' class='unselect'>Unselect</a>");
29
- this.$unselectBtn.on('click', (function(_this) {
30
- return function(e) {
31
- e.preventDefault();
32
- return _this._unselect_list_items();
33
- };
34
- })(this));
35
- return this.$el.append(this.$unselectBtn);
36
- };
37
-
38
- LoftGroupActions.prototype._bind_checkboxes = function() {
39
- return this.list.$el.on('click', '.asset .asset-checkbox input', (function(_this) {
40
- return function(e) {
41
- var selectedItems;
42
- if (!_this.loft.selectMultipleAssets) {
43
- _this._select_single_item($(e.target));
44
- }
45
- selectedItems = _this._selected_list_items();
46
- if (selectedItems.length > 0) {
47
- return _this._show();
48
- } else {
49
- return _this.hide();
50
- }
51
- };
52
- })(this));
53
- };
54
-
55
- LoftGroupActions.prototype._select_single_item = function($checkbox) {
56
- if ($checkbox.prop('checked')) {
57
- this.list.$el.find('.asset .asset-checkbox input:checked').prop('checked', false);
58
- return $checkbox.prop('checked', true);
59
- }
60
- };
61
-
62
- LoftGroupActions.prototype._selected_list_items = function() {
63
- return $.map(this.list.$el.find('.asset .asset-checkbox input:checked'), function(checkbox) {
64
- return $(checkbox).parent().parent();
65
- });
66
- };
67
-
68
- LoftGroupActions.prototype._unselect_list_items = function() {
69
- this.list.$el.find('.asset .asset-checkbox input').prop('checked', false);
70
- return this.hide();
71
- };
72
-
73
- LoftGroupActions.prototype._delete_selected_list_items = function() {
74
- var $item, $selectedItems, filesToRemoveCounter, i, len, objectId;
75
- if (confirm("Are you sure?")) {
76
- $selectedItems = this._selected_list_items();
77
- filesToRemoveCounter = $selectedItems.length;
78
- for (i = 0, len = $selectedItems.length; i < len; i++) {
79
- $item = $selectedItems[i];
80
- objectId = $item.attr('data-id');
81
- this.list.config.arrayStore.remove(objectId, {
82
- onSuccess: (function(_this) {
83
- return function() {};
84
- })(this),
85
- onError: (function(_this) {
86
- return function() {};
87
- })(this)
88
- });
89
- }
90
- return this.hide();
91
- }
92
- };
93
-
94
- LoftGroupActions.prototype._accept_selected_items = function() {
95
- var $item, $selectedItems, i, len, object, objectId, objects;
96
- $selectedItems = this._selected_list_items();
97
- objects = [];
98
- for (i = 0, len = $selectedItems.length; i < len; i++) {
99
- $item = $selectedItems[i];
100
- objectId = $item.attr('data-id');
101
- object = this.list.config.arrayStore.get(objectId);
102
- objects.push(object);
103
- }
104
- this.loft.onAcceptCallback(objects);
105
- return this.loft.closeModal();
106
- };
107
-
108
- LoftGroupActions.prototype._show = function() {
109
- return this.$el.show();
110
- };
111
-
112
- LoftGroupActions.prototype.hide = function() {
113
- return this.$el.hide();
114
- };
115
-
116
- return LoftGroupActions;
117
-
118
- })();
119
-
120
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
121
- hasProp = {}.hasOwnProperty;
122
-
123
- this.LoftAssetItem = (function(superClass) {
124
- extend(LoftAssetItem, superClass);
125
-
126
- function LoftAssetItem(module, path, object1, config) {
127
- this.module = module;
128
- this.path = path;
129
- this.object = object1;
130
- this.config = config;
131
- this.$el = $("<div class='item asset asset-" + this.object.type + "' data-id='" + this.object._id + "'></div>");
132
- this.render();
133
- }
134
-
135
- LoftAssetItem.prototype._bind_name_input = function() {
136
- this.$nameInput.on('blur', (function(_this) {
137
- return function(e) {
138
- return _this._update_name_if_changed();
139
- };
140
- })(this));
141
- return this.$nameInput.on('keyup', (function(_this) {
142
- return function(e) {
143
- if (e.keyCode === 13) {
144
- $(e.target).blur();
145
- }
146
- if (e.keyCode === 27) {
147
- return _this._cancel_name_change();
148
- }
149
- };
150
- })(this));
151
- };
152
-
153
- LoftAssetItem.prototype._edit_name = function(e) {
154
- this.$el.addClass('edit-name');
155
- return this.$nameInput.focus().select();
156
- };
157
-
158
- LoftAssetItem.prototype._cancel_name_change = function() {
159
- var name;
160
- this.$el.removeClass('edit-name');
161
- name = this.$title.html();
162
- return this.$nameInput.val(name);
163
- };
164
-
165
- LoftAssetItem.prototype._update_name_if_changed = function() {
166
- var name;
167
- this.$el.removeClass('edit-name');
168
- name = this.$nameInput.val();
169
- if (name === this.$title.html()) {
170
- return;
171
- }
172
- this.$title.html(name);
173
- return this.config.arrayStore.update(this.object._id, {
174
- '[name]': name
175
- }, {
176
- onSuccess: (function(_this) {
177
- return function(object) {};
178
- })(this),
179
- onError: (function(_this) {
180
- return function(errors) {};
181
- })(this)
182
- });
183
- };
184
-
185
- LoftAssetItem.prototype.render = function() {
186
- var name;
187
- this.$el.html('').removeClass('item-folder has-subtitle has-thumbnail');
188
- this._render_title();
189
- this._render_subtitle();
190
- this.$link = $("<a class='asset-icon' href='" + this.object.file.url + "' target='_blank'></a>");
191
- this.$el.prepend(this.$link);
192
- if (this.object.type === 'image' && this.object.grid_item_thumbnail !== '') {
193
- this.$thumbnailSmall = $("<img class='asset-thumbnail-small' src='" + this.object.item_thumbnail.small + "' />");
194
- this.$thumbnailMedium = $("<img class='asset-thumbnail-medium' src='" + this.object.item_thumbnail.medium + "' />");
195
- this.$link.append(this.$thumbnailSmall);
196
- this.$link.append(this.$thumbnailMedium);
197
- }
198
- this.$checkbox = $("<div class='asset-checkbox'></div>");
199
- this.$checkboxInput = $("<input type='checkbox' />");
200
- this.$checkbox.append(this.$checkboxInput);
201
- this.$el.prepend(this.$checkbox);
202
- name = this.$title.text();
203
- this.$name = $("<div class='asset-name'></div>");
204
- this.$nameInput = $("<input type='text' value='" + name + "' />");
205
- this.$name.append(this.$nameInput);
206
- this.$title.before(this.$name);
207
- this._bind_name_input();
208
- return this.$title.on('click', (function(_this) {
209
- return function(e) {
210
- return _this._edit_name(e);
211
- };
212
- })(this));
213
- };
214
-
215
- return LoftAssetItem;
216
-
217
- })(Item);
218
-
219
- this.Loft = (function() {
220
- function Loft(title, resource, resourcePath, arrayStoreClass, arrayStoreConfig) {
221
- var moduleConfig;
222
- this.arrayStoreClass = arrayStoreClass;
223
- this.arrayStoreConfig = arrayStoreConfig;
224
- this.module = {};
225
- this.store = {};
226
- if (this.arrayStoreClass == null) {
227
- this.arrayStoreClass = RailsArrayStore;
228
- }
229
- if (this.arrayStoreConfig == null) {
230
- this.arrayStoreConfig = {
231
- resource: resource,
232
- path: resourcePath,
233
- sortBy: 'created_at',
234
- sortReverse: true,
235
- searchable: true
236
- };
237
- }
238
- this._uploadsCounter = 0;
239
- moduleConfig = {
240
- title: title,
241
- showNestedListsAside: true,
242
- items: {
243
- loft_all: this._nested_list_config('All'),
244
- loft_images: this._nested_list_config('Images', 'image'),
245
- loft_text: this._nested_list_config('Text', 'text'),
246
- loft_archives: this._nested_list_config('Archives', 'archive'),
247
- loft_audio: this._nested_list_config('Audio', 'audio'),
248
- loft_video: this._nested_list_config('Video', 'video'),
249
- loft_other: this._nested_list_config('Other', 'other')
250
- },
251
- onModuleInit: (function(_this) {
252
- return function(module) {
253
- return _this._initialize_module(module);
254
- };
255
- })(this)
256
- };
257
- return moduleConfig;
258
- }
259
-
260
- Loft.prototype._initialize_module = function(module) {
261
- this.module = module;
262
- this.store = this.module.nestedLists.loft_all.config.arrayStore;
263
- this.module.showModal = (function(_this) {
264
- return function(assetType, selectMultipleAssets, callback) {
265
- return _this.showModal(assetType, selectMultipleAssets, callback);
266
- };
267
- })(this);
268
- this.selectMultipleAssets = true;
269
- this.module.rootList.$modalCloseBtn = $("<a href='#' class='modal-close'>Cancel</a>");
270
- this.module.rootList.$header.prepend(this.module.rootList.$modalCloseBtn);
271
- this.module.rootList.$modalCloseBtn.on('click', (function(_this) {
272
- return function(e) {
273
- e.preventDefault();
274
- return _this.closeModal();
275
- };
276
- })(this));
277
- this.module.rootList.$items.on('click', 'a', (function(_this) {
278
- return function(e) {
279
- var $item, listName;
280
- if (_this.module.$el.hasClass('module-modal')) {
281
- e.preventDefault();
282
- $item = $(e.currentTarget);
283
- listName = $item.attr('href').split('/')[2];
284
- _this.module.activeList.hide();
285
- _this.module.showList(listName);
286
- _this.module.activeList.updateItems();
287
- $item.parent().children('.active').removeClass('active');
288
- return $item.addClass('active');
289
- }
290
- };
291
- })(this));
292
- if (!chr.isMobile()) {
293
- return this.module.$el.addClass('grid-mode');
294
- }
295
- };
296
-
297
- Loft.prototype._nested_list_config = function(moduleName, assetType) {
298
- var config, storeConfig;
299
- storeConfig = {};
300
- $.extend(storeConfig, this.arrayStoreConfig);
301
- if (assetType) {
302
- $.extend(storeConfig, {
303
- urlParams: {
304
- by_type: assetType
305
- }
306
- });
307
- }
308
- config = {
309
- title: moduleName,
310
- itemTitleField: 'name',
311
- itemSubtitleField: 'created_ago',
312
- showWithParent: true,
313
- itemClass: LoftAssetItem,
314
- arrayStore: new this.arrayStoreClass(storeConfig),
315
- onListInit: (function(_this) {
316
- return function(list) {
317
- return _this._inititialize_list(list);
318
- };
319
- })(this),
320
- onListShow: (function(_this) {
321
- return function(list) {
322
- return _this._clear_assets_selection();
323
- };
324
- })(this)
325
- };
326
- return config;
327
- };
328
-
329
- Loft.prototype._inititialize_list = function(list) {
330
- list.$uploadInput = $("<input class='asset-upload' type='file' multiple='multiple' />");
331
- list.$search.before(list.$uploadInput);
332
- list.$uploadInput.on('change', (function(_this) {
333
- return function(e) {
334
- var file, files, i, len, results;
335
- files = e.target.files;
336
- if (files.length > 0) {
337
- results = [];
338
- for (i = 0, len = files.length; i < len; i++) {
339
- file = files[i];
340
- results.push(_this._upload(file, list));
341
- }
342
- return results;
343
- }
344
- };
345
- })(this));
346
- list.groupActions = new LoftGroupActions(list, this);
347
- list.$switchMode = $("<a class='assets-switch-mode' href='#'></a>");
348
- list.$backBtn.after(list.$switchMode);
349
- list.$switchMode.on('click', (function(_this) {
350
- return function(e) {
351
- e.preventDefault();
352
- return _this.module.$el.toggleClass('grid-mode');
353
- };
354
- })(this));
355
- return list.$header.on('click', '.back', (function(_this) {
356
- return function(e) {
357
- if (_this.module.$el.hasClass('module-modal')) {
358
- e.preventDefault();
359
- return _this.module.showList();
360
- }
361
- };
362
- })(this));
363
- };
364
-
365
- Loft.prototype._upload = function(file, list) {
366
- var obj;
367
- obj = {};
368
- obj["__FILE__[file]"] = file;
369
- this._start_file_upload();
370
- return this.store.push(obj, {
371
- onSuccess: (function(_this) {
372
- return function(object) {
373
- return _this._finish_file_upload(list);
374
- };
375
- })(this),
376
- onError: (function(_this) {
377
- return function(errors) {
378
- _this._finish_file_upload(list);
379
- return chr.showError('Can\'t upload file.');
380
- };
381
- })(this)
382
- });
383
- };
384
-
385
- Loft.prototype._start_file_upload = function() {
386
- this._uploadsCounter += 1;
387
- return this.module.$el.addClass('assets-uploading');
388
- };
389
-
390
- Loft.prototype._finish_file_upload = function(list) {
391
- this._uploadsCounter -= 1;
392
- if (this._uploadsCounter === 0) {
393
- this.module.$el.removeClass('assets-uploading');
394
- if (this.module.activeList.name !== 'loft_all') {
395
- return this.module.activeList.updateItems();
396
- }
397
- }
398
- };
399
-
400
- Loft.prototype._clear_assets_selection = function() {
401
- var list, name, ref, results;
402
- ref = this.module.nestedLists;
403
- results = [];
404
- for (name in ref) {
405
- list = ref[name];
406
- list.groupActions.hide();
407
- results.push(list.$items.find('.asset-checkbox').prop('checked', false));
408
- }
409
- return results;
410
- };
411
-
412
- Loft.prototype.closeModal = function() {
413
- this.selectMultipleAssets = true;
414
- this._clear_assets_selection();
415
- this.module.$el.removeClass('module-modal');
416
- return this.module.hide();
417
- };
418
-
419
- Loft.prototype.showModal = function(assetType, selectMultipleAssets1, onAcceptCallback) {
420
- if (assetType == null) {
421
- assetType = 'all';
422
- }
423
- this.selectMultipleAssets = selectMultipleAssets1 != null ? selectMultipleAssets1 : false;
424
- this.onAcceptCallback = onAcceptCallback != null ? onAcceptCallback : $.noop;
425
- this.module.$el.addClass('module-modal');
426
- this.module.show();
427
- this.module.showList("loft_" + assetType);
428
- this.module.activeList.updateItems();
429
- this.module.rootList.$items.children().removeClass('active');
430
- return this.module.rootList.$items.children("[href='#/loft/loft_" + assetType + "']").addClass('active');
431
- };
432
-
433
- return Loft;
434
-
435
- })();
436
-
437
- if (!this.RedactorPlugins) {
438
- this.RedactorPlugins = {};
439
- }
440
-
441
- RedactorPlugins.loft = function() {
442
- var methods;
443
- methods = {
444
- init: function() {
445
- var fileButton, imageButton;
446
- imageButton = this.button.add('image', 'Insert Image');
447
- this.button.addCallback(imageButton, this.loft.showImagesModal);
448
- fileButton = this.button.add('file', 'Insert File');
449
- return this.button.addCallback(fileButton, this.loft.showAllModal);
450
- },
451
- showImagesModal: function() {
452
- return chr.modules.loft.showModal('images', true, (function(_this) {
453
- return function(objects) {
454
- return _this.loft.insertImages(objects);
455
- };
456
- })(this));
457
- },
458
- showAllModal: function() {
459
- var multipleAssets;
460
- multipleAssets = this.selection.getText() === '';
461
- return chr.modules.loft.showModal('all', multipleAssets, (function(_this) {
462
- return function(objects) {
463
- return _this.loft.insertFiles(objects);
464
- };
465
- })(this));
466
- },
467
- insertFiles: function(objects) {
468
- var asset, html, i, len, links, selectedText;
469
- if (objects.length > 0) {
470
- selectedText = this.selection.getText();
471
- if (selectedText !== '') {
472
- asset = objects[0];
473
- html = "<a href='" + asset.file.url + "' target='_blank'>" + selectedText + "</a>";
474
- } else {
475
- links = [];
476
- for (i = 0, len = objects.length; i < len; i++) {
477
- asset = objects[i];
478
- links.push("<a href='" + asset.file.url + "' target='_blank'>" + asset.name + "</a>");
479
- }
480
- html = links.join('<br>');
481
- }
482
- return this.insert.html(html, false);
483
- }
484
- },
485
- insertImages: function(objects) {
486
- var asset, html, i, images, len;
487
- if (objects.length > 0) {
488
- images = [];
489
- for (i = 0, len = objects.length; i < len; i++) {
490
- asset = objects[i];
491
- images.push("<img src='" + asset.file.url + "' alt='" + asset.name + "' />");
492
- }
493
- html = images.join('<br>');
494
- return this.insert.html(html, false);
495
- }
496
- }
497
- };
498
- return methods;
499
- };
500
-
501
-
502
-
503
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
504
- hasProp = {}.hasOwnProperty;
505
-
506
- this.InputLoftImage = (function(superClass) {
507
- extend(InputLoftImage, superClass);
508
-
509
- function InputLoftImage() {
510
- return InputLoftImage.__super__.constructor.apply(this, arguments);
511
- }
512
-
513
- InputLoftImage.prototype._add_input = function() {
514
- var base;
515
- if ((base = this.config).placeholder == null) {
516
- base.placeholder = 'Image url';
517
- }
518
- this.$input = $("<input type='string' name='" + this.name + "' value='" + (this._safe_value()) + "' id='" + this.name + "' />");
519
- this.$el.append(this.$input);
520
- this.$input.on('change', (function(_this) {
521
- return function(e) {
522
- return _this.updateValue($(e.target).val());
523
- };
524
- })(this));
525
- this._add_image();
526
- this._add_choose_button();
527
- this._add_remove_button();
528
- return this._update_input_class();
529
- };
530
-
531
- InputLoftImage.prototype._add_image = function() {
532
- this.$image = $("<a href='' target='_blank' class='image'><img src='' /></a>");
533
- this.$el.append(this.$image);
534
- return this._update_image();
535
- };
536
-
537
- InputLoftImage.prototype._add_choose_button = function() {
538
- this.$chooseBtn = $("<a href='#' class='choose'></a><br/>");
539
- this.$el.append(this.$chooseBtn);
540
- this._update_choose_button_title();
541
- return this.$chooseBtn.on('click', (function(_this) {
542
- return function(e) {
543
- e.preventDefault();
544
- return chr.modules.loft.showModal('images', false, function(objects) {
545
- var asset;
546
- asset = objects[0];
547
- return _this.updateValue(asset.file.url);
548
- });
549
- };
550
- })(this));
551
- };
552
-
553
- InputLoftImage.prototype._add_remove_button = function() {
554
- this.$removeBtn = $("<a href='#' class='remove'>Remove</a>");
555
- this.$el.append(this.$removeBtn);
556
- return this.$removeBtn.on('click', (function(_this) {
557
- return function(e) {
558
- e.preventDefault();
559
- if (confirm('Are you sure?')) {
560
- return _this.updateValue('');
561
- }
562
- };
563
- })(this));
564
- };
565
-
566
- InputLoftImage.prototype._update_image = function() {
567
- var url;
568
- url = this.value;
569
- this.$image.attr('href', this.value).children().attr('src', this.value);
570
- if (this.value === '') {
571
- return this.$image.hide();
572
- } else {
573
- return this.$image.show();
574
- }
575
- };
576
-
577
- InputLoftImage.prototype._update_choose_button_title = function() {
578
- var title;
579
- title = this.value === '' ? 'Choose or upload' : 'Choose other or upload';
580
- return this.$chooseBtn.html(title);
581
- };
582
-
583
- InputLoftImage.prototype._update_input_class = function() {
584
- if (this.value === '') {
585
- return this.$el.removeClass('has-value');
586
- } else {
587
- return this.$el.addClass('has-value');
588
- }
589
- };
590
-
591
- InputLoftImage.prototype.updateValue = function(value) {
592
- this.value = value;
593
- this.$input.val(this.value);
594
- this._update_image();
595
- this._update_choose_button_title();
596
- return this._update_input_class();
597
- };
598
-
599
- return InputLoftImage;
600
-
601
- })(InputString);
602
-
603
- chr.formInputs['loft-image'] = InputLoftImage;
data/package.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "name": "loft",
3
- "version": "0.1.5",
4
- "devDependencies": {
5
- "grunt": "^0.4.5",
6
- "grunt-contrib-clean": "^0.6.0",
7
- "grunt-contrib-coffee": "^0.13.0",
8
- "grunt-contrib-concat": "^0.5.1"
9
- }
10
- }