card 1.95.3 → 1.96.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/card.rb +10 -2
- data/lib/card/migration/import.rb +1 -1
- data/lib/card/set.rb +1 -1
- data/lib/card/set/event.rb +63 -65
- data/lib/card/set/event/callbacks.rb +21 -0
- data/lib/card/set/event/delayed_event.rb +11 -16
- data/lib/card/set/event/options.rb +78 -0
- data/lib/card/set/format.rb +5 -93
- data/lib/card/set/format/abstract_format.rb +104 -0
- data/mod/Modfile +1 -0
- data/mod/basic_formats/set/all/all_csv.rb +1 -1
- data/mod/basic_formats/set/all/json.rb +61 -4
- data/mod/basic_formats/spec/set/all/json_spec.rb +51 -1
- data/mod/basic_formats/spec/shared_context/json_shared_context.rb +40 -0
- data/mod/bootstrap/lib/stylesheets/style_bootstrap_cards.scss +17 -1
- data/mod/bootstrap/set/abstract/bootswatch_theme.rb +2 -12
- data/mod/bootstrap/set/abstract/bootswatch_theme/html_views.rb +31 -0
- data/mod/bootstrap/set/type/customized_bootswatch_skin.rb +12 -0
- data/mod/bootstrap/set/type/customized_bootswatch_skin/core.haml +5 -0
- data/mod/bootstrap/set/type/customized_bootswatch_skin/html_views.rb +36 -0
- data/mod/bootstrap/set/type_plus_right/customized_bootswatch_skin/colors.rb +14 -10
- data/mod/bootstrap/set/type_plus_right/customized_bootswatch_skin/colors/_colorpicker.haml +1 -1
- data/mod/bootstrap/set/type_plus_right/customized_bootswatch_skin/colors/editor.haml +13 -9
- data/mod/core/chunk/link.rb +8 -0
- data/mod/core/set/abstract/code_file.rb +5 -0
- data/mod/core/set/all/chunk.rb +46 -24
- data/mod/core/set/all/event_conditions.rb +32 -11
- data/mod/core/set/all/export.rb +3 -5
- data/mod/core/set/all/item.rb +16 -0
- data/mod/core/set/all/name.rb +1 -0
- data/mod/core/set/all/references.rb +25 -16
- data/mod/core/set/all/rename.rb +20 -21
- data/mod/core/set/all/trash.rb +13 -4
- data/mod/core/spec/set/all/actify_spec.rb +4 -4
- data/mod/core/spec/set/all/event_conditions_spec.rb +68 -10
- data/mod/core/spec/set/all/export_spec.rb +7 -4
- data/mod/core/spec/set/all/references_spec.rb +38 -1
- data/mod/core/spec/set/all/rename_spec.rb +15 -9
- data/mod/follow/spec/set/right/followers_spec.rb +1 -1
- data/mod/follow/spec/set/right/following_spec.rb +4 -8
- data/mod/follow/spec/set/type/notification_template_spec.rb +1 -1
- data/mod/history/set/all/act_view.rb +2 -2
- data/mod/item/set/all/bar.haml +12 -0
- data/mod/item/set/all/bar.rb +77 -0
- data/mod/item/set/all/box.haml +10 -0
- data/mod/item/set/all/box.rb +8 -0
- data/mod/item/set/all/expanded_bar.haml +10 -0
- data/mod/machines/file/all_script_machine_output/file.js +30622 -66
- data/mod/machines/file/all_style_machine_output/file.css +3 -3
- data/mod/machines/file/script_html5shiv_printshiv_machine_output/file.js +1 -1
- data/mod/machines/lib/javascript/decko_slot.js.coffee +18 -13
- data/mod/machines/set/abstract/skin_box.rb +34 -0
- data/mod/machines/set/abstract/skin_box/box_bottom.haml +4 -0
- data/mod/machines/set/type/skin.rb +1 -1
- data/mod/pointer/set/abstract/01_paging.rb +49 -4
- data/mod/pointer/set/abstract/01_paging/paging_links.rb +6 -6
- data/mod/pointer/set/abstract/02_pointer/html_views.rb +10 -0
- data/mod/pointer/set/abstract/02_pointer/other_views.rb +9 -5
- data/mod/pointer/spec/set/abstract/pointer/html_views_spec.rb +4 -10
- data/mod/pointer/spec/set/abstract/pointer/other_views_spec.rb +20 -1
- data/mod/search/set/abstract/01_filter_form_helper.rb +4 -4
- data/mod/search/set/abstract/02_search_params.rb +1 -1
- data/mod/search/set/abstract/03_filter.rb +8 -0
- data/mod/search/set/abstract/search.rb +10 -0
- data/mod/settings/set/right/style.rb +13 -0
- data/mod/settings/set/right/style/editor.haml +4 -4
- data/mod/standard/set/all/path.rb +6 -0
- data/mod/standard/set/type/list.rb +3 -2
- data/mod/standard/set/type/listed_by.rb +5 -1
- data/mod/standard/spec/content/chunk/include_spec.rb +2 -2
- data/mod/standard/spec/set/all/rich_html/editing_spec.rb +4 -69
- data/mod/standard/spec/set/type/listed_by_spec.rb +2 -2
- data/mod/standard/spec/set/type/search_type_spec.rb +56 -0
- data/mod/standard/spec/set/type/set/html_views_spec.rb +5 -9
- data/mod/utility/set/abstract/bs_badge.rb +21 -0
- data/mod/utility/set/abstract/bs_badge/bs_badge.haml +5 -0
- data/mod/utility/set/abstract/bs_badge/labeled_badge.haml +5 -0
- data/mod/utility/set/abstract/bs_badge/tab_badge.haml +5 -0
- data/mod/utility/set/abstract/media.rb +27 -0
- data/mod/utility/set/abstract/media/media_snippet.haml +9 -0
- metadata +28 -10
- data/mod/machines/set/abstract/skin_thumbnail.rb +0 -28
- data/mod/machines/set/abstract/skin_thumbnail/thumbnail.haml +0 -10
@@ -0,0 +1,104 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class Card
|
4
|
+
module Set
|
5
|
+
module Format
|
6
|
+
# All Format modules are extended with this module in order to support
|
7
|
+
# the basic format API, including view, layout, and basket definitions
|
8
|
+
module AbstractFormat
|
9
|
+
include Set::Basket
|
10
|
+
include Set::Format::HamlViews
|
11
|
+
|
12
|
+
mattr_accessor :views
|
13
|
+
self.views = Hash.new { |h, k| h[k] = {} }
|
14
|
+
|
15
|
+
def before view, &block
|
16
|
+
define_method "_before_#{view}", &block
|
17
|
+
end
|
18
|
+
|
19
|
+
def view view, *args, &block
|
20
|
+
# view = view.to_viewname.key.to_sym
|
21
|
+
interpret_view_opts view, args[0] if block_given?
|
22
|
+
view_method_block = view_block(view, args, &block)
|
23
|
+
if async_view? args
|
24
|
+
# This case makes only sense for HtmlFormat
|
25
|
+
# but I don't see an easy way to override class methods for a specific
|
26
|
+
# format. All formats are extended with this general module. So
|
27
|
+
# a HtmlFormat.view method would be overridden by AbstractFormat.view
|
28
|
+
# We need something like AbstractHtmlFormat for that.
|
29
|
+
define_async_view_method view, &view_method_block
|
30
|
+
else
|
31
|
+
define_standard_view_method view, &view_method_block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def view_for_override viewname
|
36
|
+
view viewname do
|
37
|
+
"override '#{viewname}' view"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def define_standard_view_method view, &block
|
42
|
+
views[self][view] = block
|
43
|
+
define_method "_view_#{view}", &block
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_async_view_method view, &block
|
47
|
+
view_content = "#{view}_async_content"
|
48
|
+
define_standard_view_method view_content, &block
|
49
|
+
define_standard_view_method view do
|
50
|
+
%(<card-view-placeholder data-url="#{path view: view_content}" />)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def interpret_view_opts view, opts
|
55
|
+
return unless opts.present?
|
56
|
+
Card::Format.interpret_view_opts view, opts
|
57
|
+
extract_view_cache_rules view, opts.delete(:cache)
|
58
|
+
end
|
59
|
+
|
60
|
+
def extract_view_cache_rules view, cache_rule
|
61
|
+
return unless cache_rule
|
62
|
+
methodname = Card::Format.view_cache_setting_method view
|
63
|
+
define_method(methodname) { cache_rule }
|
64
|
+
end
|
65
|
+
|
66
|
+
def view_block view, args, &block
|
67
|
+
return haml_view_block(view, wrap_with_slot?(args), &block) if haml_view?(args)
|
68
|
+
block_given? ? block : lookup_alias_block(view, args)
|
69
|
+
end
|
70
|
+
|
71
|
+
def haml_view? args
|
72
|
+
args.first.is_a?(Hash) && args.first[:template] == :haml
|
73
|
+
end
|
74
|
+
|
75
|
+
def wrap_with_slot? args
|
76
|
+
args.first.is_a?(Hash) && args.first[:slot]
|
77
|
+
end
|
78
|
+
|
79
|
+
def async_view? args
|
80
|
+
args.first.is_a?(Hash) && args.first[:async]
|
81
|
+
end
|
82
|
+
|
83
|
+
def lookup_alias_block view, args
|
84
|
+
opts = args[0].is_a?(Hash) ? args.shift : { view: args.shift }
|
85
|
+
opts[:mod] ||= self
|
86
|
+
opts[:view] ||= view
|
87
|
+
views[opts[:mod]][opts[:view]] || begin
|
88
|
+
raise "cannot find #{opts[:view]} view in #{opts[:mod]}; " \
|
89
|
+
"failed to alias #{view} in #{self}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def source_location
|
94
|
+
set_module.source_location
|
95
|
+
end
|
96
|
+
|
97
|
+
# remove the format part of the module name
|
98
|
+
def set_module
|
99
|
+
Card.const_get name.split("::")[0..-2].join("::")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/mod/Modfile
CHANGED
@@ -79,7 +79,7 @@ format :csv do
|
|
79
79
|
def column_titles extra_titles=nil
|
80
80
|
res = Array extra_titles
|
81
81
|
card1 = Card.fetch card.item_names(limit: 1).first
|
82
|
-
card1.
|
82
|
+
card1.nest_chunks.each do |chunk|
|
83
83
|
res << column_title(chunk.options)
|
84
84
|
end
|
85
85
|
res.compact
|
@@ -1,4 +1,9 @@
|
|
1
1
|
format :json do
|
2
|
+
# because card.item_cards returns "[[#{self}]]"
|
3
|
+
def item_cards
|
4
|
+
uniq_nested_cards
|
5
|
+
end
|
6
|
+
|
2
7
|
AUTOCOMPLETE_LIMIT = 8 # number of name suggestions for autocomplete text fields
|
3
8
|
|
4
9
|
def default_nest_view
|
@@ -13,8 +18,11 @@ format :json do
|
|
13
18
|
params[:max_depth].present? ? params[:max_depth].to_i : 1
|
14
19
|
end
|
15
20
|
|
21
|
+
# TODO: support layouts in json
|
22
|
+
# eg layout=stamp gives you the metadata currently in "page" view
|
23
|
+
# and layout=none gives you ONLY the requested view (default atom)
|
16
24
|
def show view, args
|
17
|
-
view ||= :
|
25
|
+
view ||= :molecule
|
18
26
|
raw = render! view, args
|
19
27
|
return raw if raw.is_a? String
|
20
28
|
method = params[:compress] ? :generate : :pretty_generate
|
@@ -54,20 +62,69 @@ format :json do
|
|
54
62
|
hash
|
55
63
|
end
|
56
64
|
|
57
|
-
view :
|
65
|
+
view :page, cache: :never do
|
58
66
|
{ url: request_url,
|
59
67
|
timestamp: Time.now.to_s,
|
60
68
|
card: _render_atom }
|
61
69
|
end
|
62
70
|
|
71
|
+
view :content do
|
72
|
+
render_page
|
73
|
+
end
|
74
|
+
|
75
|
+
view :core do
|
76
|
+
{ card.name => card.content }
|
77
|
+
end
|
78
|
+
|
79
|
+
view :nucleus, cache: :never do
|
80
|
+
{
|
81
|
+
id: card.id,
|
82
|
+
name: card.name,
|
83
|
+
url: path(format: :json),
|
84
|
+
html_url: path
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
63
88
|
view :atom, cache: :never do
|
64
|
-
h =
|
89
|
+
h = _render_nucleus
|
90
|
+
h[:type] = card.type_name
|
91
|
+
h[:type_url] = path mark: card.type_name, format: :json
|
92
|
+
h[:atom_url] = path format: :json, view: :atom
|
93
|
+
h[:nucleus_url] = path format: :json, view: :nucleus
|
65
94
|
h[:content] = card.db_content unless card.structure
|
66
95
|
h[:codename] = card.codename if card.codename
|
67
|
-
h[:value] = _render_core if depth < max_depth
|
68
96
|
h
|
69
97
|
end
|
70
98
|
|
99
|
+
view :items, cache: :never do
|
100
|
+
item_cards.map do |i_card|
|
101
|
+
nest i_card
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
view :links, cache: :never do
|
106
|
+
card.link_chunks.map do |chunk|
|
107
|
+
if chunk.referee_name
|
108
|
+
path mark: chunk.referee_name, format: :json
|
109
|
+
else
|
110
|
+
link_to_resource chunk.link_target
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
view :ancestors, cache: :never do
|
116
|
+
card.name.ancestors.map do |name|
|
117
|
+
nest name
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
view :molecule, cache: :never do
|
122
|
+
_render_atom.merge items: _render_items,
|
123
|
+
links: _render_links,
|
124
|
+
ancestors: _render_ancestors
|
125
|
+
|
126
|
+
end
|
127
|
+
|
71
128
|
# minimum needed to re-fetch card
|
72
129
|
view :cast, cache: :never do
|
73
130
|
card.cast
|
@@ -1,6 +1,56 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
describe Card::Set::All::Json
|
3
|
+
RSpec.describe Card::Set::All::Json do
|
4
|
+
include_context "json context"
|
5
|
+
specify "nucleus view" do
|
6
|
+
expect_view(:nucleus, format: :json)
|
7
|
+
.to eq nucleus_values
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "atom view" do
|
11
|
+
expect_view(:atom, format: :json)
|
12
|
+
.to eq atom_values
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "molecule view" do
|
16
|
+
context "with internal link" do
|
17
|
+
it "has link url" do
|
18
|
+
expect_view(:molecule, format: :json)
|
19
|
+
.to eq atom_values.merge items: [],
|
20
|
+
links: [json_url("Z")],
|
21
|
+
ancestors: []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with external link" do
|
26
|
+
def card_subject
|
27
|
+
@card ||= create "external link",
|
28
|
+
content: "[[http://xkcd.com|link text]]" \
|
29
|
+
"[[/Z]]"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "has link urls" do
|
33
|
+
expect_view(:molecule, format: :json)
|
34
|
+
.to eq atom_values.merge items: [],
|
35
|
+
links: ["http://xkcd.com", url("Z")],
|
36
|
+
ancestors: []
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with nests" do
|
41
|
+
def card_subject
|
42
|
+
Card["B"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has nests" do
|
46
|
+
expect_view(:molecule, format: :json)
|
47
|
+
.to eq atom_values.merge items: [atom_values(Card["Z"])],
|
48
|
+
links: [],
|
49
|
+
ancestors: []
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
4
54
|
context "status view" do
|
5
55
|
it "handles real and virtual cards" do
|
6
56
|
jf = Card::Format::JsonFormat
|
@@ -0,0 +1,40 @@
|
|
1
|
+
RSpec.shared_context "json context", shared_context: :json do
|
2
|
+
before do
|
3
|
+
Card::Env[:host] = "json.com"
|
4
|
+
Card::Env[:protocol] = "http://"
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:root) { "http://json.com" }
|
8
|
+
|
9
|
+
def json_url target, query=nil
|
10
|
+
url "#{target}.json", query
|
11
|
+
end
|
12
|
+
|
13
|
+
def url target, query=nil
|
14
|
+
["#{root}/#{target}", query].compact.join "?"
|
15
|
+
end
|
16
|
+
|
17
|
+
def nucleus_values card=card_subject
|
18
|
+
{
|
19
|
+
id: card.id,
|
20
|
+
name: card.name,
|
21
|
+
url: json_url(card.name.url_key),
|
22
|
+
html_url: "#{root}/#{card.name.url_key}"
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def atom_values card=card_subject, structured: false
|
27
|
+
values = nucleus_values(card).merge(
|
28
|
+
type: card.type_name,
|
29
|
+
type_url: json_url(card.type_name),
|
30
|
+
atom_url: json_url(card.name.url_key, "view=atom"),
|
31
|
+
nucleus_url: json_url(card.name.url_key, "view=nucleus")
|
32
|
+
)
|
33
|
+
values[:content] = card.content unless structured
|
34
|
+
values
|
35
|
+
end
|
36
|
+
|
37
|
+
def structured_atom_values card=card_subject
|
38
|
+
atom_values card, structured: true
|
39
|
+
end
|
40
|
+
end
|
@@ -11,6 +11,7 @@
|
|
11
11
|
$label_color: $gray-600;
|
12
12
|
$header_color: $gray-200;
|
13
13
|
$credit_color: $primary;
|
14
|
+
$bar_stripe_color: $gray-700;
|
14
15
|
|
15
16
|
header {
|
16
17
|
a {
|
@@ -57,7 +58,6 @@ form {
|
|
57
58
|
padding: 0px;
|
58
59
|
}
|
59
60
|
|
60
|
-
|
61
61
|
.link-muted {
|
62
62
|
color: $text-muted;
|
63
63
|
&:hover {
|
@@ -65,6 +65,13 @@ form {
|
|
65
65
|
}
|
66
66
|
}
|
67
67
|
|
68
|
+
.grow-1 {
|
69
|
+
flex-grow: 1;
|
70
|
+
}
|
71
|
+
.grow-2 {
|
72
|
+
flex-grow: 2;
|
73
|
+
}
|
74
|
+
|
68
75
|
/*-------- Special Pages --------*/
|
69
76
|
|
70
77
|
/*-- sign in page --*/
|
@@ -336,3 +343,12 @@ body.mceContentBody {
|
|
336
343
|
display: none !important;
|
337
344
|
}
|
338
345
|
}
|
346
|
+
|
347
|
+
.bar-top.left-stripe, .bar.left-stripe {
|
348
|
+
border-left: 4px solid $bar_stripe_color !important;
|
349
|
+
}
|
350
|
+
|
351
|
+
.bar-bottom .bar.left-stripe {
|
352
|
+
border-left: 3px solid $bar_stripe_color !important;
|
353
|
+
}
|
354
|
+
|
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# The content of a bootswatch theme card consists of four parts:
|
12
12
|
# * pre_variables: hard-coded theme independent stuff
|
13
|
-
# and bootstrap functions to make
|
13
|
+
# and bootstrap functions to make them available in the variables part
|
14
14
|
# * variables: the content from `_variables.scss`,
|
15
15
|
# * post_variables: the bootstrap css and libraries like select2 and
|
16
16
|
# bootstrap-colorpicker that depend on the theme
|
@@ -39,7 +39,7 @@
|
|
39
39
|
include_set Abstract::Machine
|
40
40
|
include_set Type::Scss
|
41
41
|
include_set Abstract::CodeFile
|
42
|
-
include_set Abstract::
|
42
|
+
include_set Abstract::SkinBox
|
43
43
|
|
44
44
|
CONTENT_PARTS = %i[pre_variables variables post_variables stylesheets].freeze
|
45
45
|
|
@@ -155,13 +155,3 @@ def source_dir
|
|
155
155
|
@source_dir ||=
|
156
156
|
::File.expand_path "../../../vendor/bootswatch/dist/#{theme_name}", __FILE__
|
157
157
|
end
|
158
|
-
|
159
|
-
format :html do
|
160
|
-
view :thumbnail, template: :haml do
|
161
|
-
voo.show! :customize_button, :thumbnail_image
|
162
|
-
end
|
163
|
-
|
164
|
-
view :closed_content do
|
165
|
-
""
|
166
|
-
end
|
167
|
-
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
include_set Abstract::Media
|
2
|
+
include_set Abstract::BsBadge
|
3
|
+
|
4
|
+
format :html do
|
5
|
+
before :box do
|
6
|
+
super()
|
7
|
+
voo.show! :customize_button, :box_middle
|
8
|
+
end
|
9
|
+
|
10
|
+
view :closed_content do
|
11
|
+
""
|
12
|
+
end
|
13
|
+
|
14
|
+
view :bar_left do
|
15
|
+
class_up "card-title", "my-0 ml-2"
|
16
|
+
class_up "media-left", "m-0", true
|
17
|
+
text_with_image size: :small, title: "", text: _render_title,
|
18
|
+
media_opts: { class: "align-items-center" }
|
19
|
+
# field_nest(:image, view: :core) + wrap_with(:h4, render(:title))
|
20
|
+
end
|
21
|
+
|
22
|
+
view :bar_right do
|
23
|
+
customize_button text: "Customize"
|
24
|
+
end
|
25
|
+
|
26
|
+
view :bar_bottom do
|
27
|
+
wrap_with :code do
|
28
|
+
render_core
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -12,6 +12,18 @@ card_accessor :colors
|
|
12
12
|
card_accessor :variables
|
13
13
|
card_accessor :stylesheets
|
14
14
|
|
15
|
+
def top_level_item_cards
|
16
|
+
cards = PRE_VARIABLES_CARD_NAMES.map { |n| Card[n] }
|
17
|
+
cards += [colors_card, variables_card]
|
18
|
+
cards += POST_VARIABLES_CARD_NAMES.map { |n| Card[n] }
|
19
|
+
cards << stylesheets_card
|
20
|
+
cards
|
21
|
+
end
|
22
|
+
|
23
|
+
def editable_item_cards
|
24
|
+
[colors_card, variables_card, stylesheets_card]
|
25
|
+
end
|
26
|
+
|
15
27
|
def variables_card_names
|
16
28
|
%i[colors variables].map { |s| Card.fetch_name name, s }
|
17
29
|
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
%h5
|
2
|
+
Skin configuration from simplest to most advanced
|
3
|
+
= field_nest :colors, view: :bar, title: "Palette and uses of colors"
|
4
|
+
= field_nest :variables, view: :bar, title: "Additional SCSS variables", show: :edit_button
|
5
|
+
= field_nest :stylesheets, view: :bar, title: "SCSS and CSS stylesheets", show: :edit_button
|