card 1.93.5 → 1.93.6
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/VERSION +1 -1
- data/db/migrate_core_cards/data/1.12_stylesheets/classic_cards.scss +1 -1
- data/db/migrate_core_cards/data/1.12_stylesheets/traditional.scss +2 -1
- data/lib/card/format/nest.rb +4 -1
- data/lib/card/format/nest/mode.rb +11 -3
- data/lib/card/query.rb +6 -2
- data/lib/card/query/sorting.rb +21 -12
- data/lib/card/query/sql_statement.rb +1 -2
- data/lib/card/view/options.rb +17 -12
- data/mod/Modfile +1 -0
- data/mod/core/layout/simple_modal.html +3 -0
- data/mod/core/set/all/fetch_helper.rb +42 -30
- data/mod/core/spec/format/html_format_spec.rb +10 -17
- data/mod/core/spec/set/all/fetch_helper_spec.rb +48 -0
- data/mod/machines/file/all_script_machine_output/file.js +132 -18
- data/mod/machines/lib/javascript/decko.js.coffee +11 -2
- data/mod/machines/lib/javascript/decko_filter.js.coffee +116 -9
- data/mod/machines/lib/stylesheets/style_cards.scss +24 -3
- data/mod/pointer/lib/javascript/script_pointer_config.js.coffee +16 -6
- data/mod/pointer/set/abstract/00_paging_params.rb +17 -4
- data/mod/pointer/set/abstract/02_pointer/filtered.rb +48 -0
- data/mod/pointer/set/self/input_options.rb +1 -0
- data/mod/pointer/spec/set/self/input_options_spec.rb +1 -1
- data/mod/pointer/template/abstract/02_pointer/filtered/filter_items.haml +34 -0
- data/mod/pointer/template/abstract/02_pointer/filtered/filtered_list_input.haml +30 -0
- data/mod/search/lib/card/filter_query.rb +81 -0
- data/mod/search/set/abstract/00_filter_helper.rb +51 -0
- data/mod/search/set/abstract/01_filter_form_helper.rb +77 -0
- data/mod/search/set/abstract/01_search_params.rb +3 -11
- data/mod/search/set/abstract/02_filter_formgroups.rb +134 -0
- data/mod/search/set/abstract/03_filter.rb +117 -0
- data/mod/search/set/abstract/04_right_filter_form.rb +23 -0
- data/mod/search/set/abstract/search.rb +44 -10
- data/mod/search/set/abstract/wql_search.rb +22 -18
- data/mod/search/spec/set/{all → abstract}/filter_spec.rb +6 -5
- data/mod/search/template/{all/filter → abstract/03_filter}/_filter_input.haml +0 -0
- data/mod/search/template/{all/filter → abstract/03_filter}/filter_form.haml +9 -7
- data/mod/search/template/abstract/search/checkbox_item.haml +7 -0
- data/mod/search/template/abstract/search/select_item.haml +14 -0
- data/mod/standard/set/all/rich_html/editing.rb +4 -4
- data/mod/standard/set/all/rich_html/form_elements.rb +11 -2
- data/mod/standard/set/all/rich_html/modal.rb +26 -19
- data/mod/standard/set/all/rich_html/new.rb +8 -2
- data/mod/standard/set/all/rich_html/wrapper.rb +22 -18
- data/mod/standard/set/type/cardtype.rb +2 -2
- data/mod/standard/spec/set/all/rich_html/editing_spec.rb +0 -1
- data/mod/utility/set/abstract/utility.rb +13 -0
- data/mod/utility/spec/set/abstract/utility_spec.rb +16 -0
- metadata +21 -7
- data/mod/search/set/all/filter.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0adcfab0f64530119b1670a194d67fde9845ad6
|
4
|
+
data.tar.gz: 3febe6d143c9de76acff582cbddd9ec8fded0104
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9f35f827cce3f73f984671c7a09f0d6adeff29523503f6b46b64bcfdee09c71449dcae5ab2356084f81788a9122a24821dc07a02b0036c9ee79f28ee2f699ae
|
7
|
+
data.tar.gz: f843c07e3dd51ae50d2cae972cdfd307706b7e8ae1b0057cd83dd2d0256b9336de707b5b9e9e49353881aaf526331559d1dcf3f4bd05da2e1a1fb73c61d1ca8d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.6
|
@@ -1,5 +1,6 @@
|
|
1
1
|
/*
|
2
|
-
This "traditional" styling is for backwards compatibility.
|
2
|
+
This "traditional" styling is for backwards compatibility.
|
3
|
+
It is not intended for use in decks created after Wagnversion 1.12.
|
3
4
|
|
4
5
|
There are three types of rules here:
|
5
6
|
1. rules applying to selectors no longer included in standard layouts (#menu, #logo, #credit)
|
data/lib/card/format/nest.rb
CHANGED
@@ -17,7 +17,10 @@ class Card
|
|
17
17
|
return "" if nest_invisible?
|
18
18
|
nested_card = fetch_nested_card cardish, options
|
19
19
|
view, options = interpret_nest_options nested_card, options
|
20
|
-
|
20
|
+
|
21
|
+
with_nest_mode options.delete(:mode) do
|
22
|
+
nest_render nested_card, view, options, override, &block
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
# nested by another card's content
|
@@ -18,12 +18,20 @@ class Card
|
|
18
18
|
# run block with new_mode as nest_mode, then return to prior mode
|
19
19
|
# @param new_mode [Symbol] :normal, :closed, :edit, or :template
|
20
20
|
# @return block result
|
21
|
-
def with_nest_mode new_mode
|
21
|
+
def with_nest_mode new_mode, &block
|
22
|
+
if new_mode
|
23
|
+
with_altered_nest_mode new_mode, &block
|
24
|
+
else
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_altered_nest_mode new_mode
|
22
30
|
old_mode = nest_mode
|
23
31
|
@nest_mode = new_mode
|
24
|
-
|
32
|
+
yield
|
33
|
+
ensure
|
25
34
|
@nest_mode = old_mode
|
26
|
-
result
|
27
35
|
end
|
28
36
|
|
29
37
|
# view to be rendered in current mode
|
data/lib/card/query.rb
CHANGED
@@ -78,7 +78,7 @@ class Card
|
|
78
78
|
OPERATORS =
|
79
79
|
%w(!= = =~ < > in ~).each_with_object({}) { |v, h| h[v] = v }.merge(
|
80
80
|
{
|
81
|
-
eq: "=", gt: ">", lt: "<", match: "~", ne: "!=", "not in"
|
81
|
+
eq: "=", gt: ">", lt: "<", match: "~", ne: "!=", "not in": "not in"
|
82
82
|
}.stringify_keys
|
83
83
|
)
|
84
84
|
|
@@ -152,7 +152,11 @@ class Card
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def limit
|
155
|
-
|
155
|
+
mods[:limit].to_i
|
156
|
+
end
|
157
|
+
|
158
|
+
def full?
|
159
|
+
!superquery && mods[:return] != "count"
|
156
160
|
end
|
157
161
|
end
|
158
162
|
end
|
data/lib/card/query/sorting.rb
CHANGED
@@ -1,34 +1,43 @@
|
|
1
1
|
class Card
|
2
2
|
class Query
|
3
3
|
module Sorting
|
4
|
-
|
4
|
+
SORT_BY_ITEM_JOIN_MAP = { left: "left_id", right: "right_id" }.freeze
|
5
5
|
|
6
6
|
def sort val
|
7
|
-
return nil
|
7
|
+
return nil unless full?
|
8
8
|
sort_field = val[:return] || "db_content"
|
9
|
+
val = val.clone
|
9
10
|
item = val.delete(:item) || "left"
|
10
|
-
|
11
11
|
if sort_field == "count"
|
12
12
|
sort_by_count val, item
|
13
|
-
elsif (join_field = SORT_JOIN_TO_ITEM_MAP[item.to_sym])
|
14
|
-
sq = join_cards(val, to_field: join_field,
|
15
|
-
side: "LEFT",
|
16
|
-
conditions_on_join: true)
|
17
|
-
@mods[:sort] ||= "#{sq.table_alias}.#{sort_field}"
|
18
13
|
else
|
19
|
-
|
14
|
+
sort_by_item_join val, item, sort_field
|
20
15
|
end
|
21
16
|
end
|
22
17
|
|
18
|
+
def sort_by_item_join val, item, sort_field
|
19
|
+
join_field = sort_by_item_join_field item
|
20
|
+
join = join_cards val, to_field: join_field,
|
21
|
+
side: "LEFT",
|
22
|
+
conditions_on_join: true
|
23
|
+
@mods[:sort] ||= "#{join.table_alias}.#{sort_field}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def sort_by_item_join_field item
|
27
|
+
SORT_BY_ITEM_JOIN_MAP[item.to_sym] || sort_method_not_implemented(:join, item)
|
28
|
+
end
|
29
|
+
|
23
30
|
# EXPERIMENTAL!
|
24
31
|
def sort_by_count val, item
|
25
32
|
method_name = "sort_by_count_#{item}"
|
26
|
-
unless respond_to?
|
27
|
-
raise Card::Error::BadQuery, "count with item: #{item} not yet implemented"
|
28
|
-
end
|
33
|
+
sort_by_count_not_implemented :count, item unless respond_to? method_name
|
29
34
|
send method_name, val
|
30
35
|
end
|
31
36
|
|
37
|
+
def sort_method_not_implemented method, item
|
38
|
+
raise Card::Error::BadQuery, "sorting by ##{method}/#{item} not yet implemented"
|
39
|
+
end
|
40
|
+
|
32
41
|
def sort_by_count_referred_to val
|
33
42
|
@mods[:sort] = "coalesce(count,0)" # needed for postgres
|
34
43
|
cs = Query.new(
|
data/lib/card/view/options.rb
CHANGED
@@ -16,17 +16,18 @@ class Card
|
|
16
16
|
|
17
17
|
@keymap = {
|
18
18
|
carditect: [
|
19
|
-
:view,
|
20
|
-
:nest_name,
|
21
|
-
:nest_syntax,
|
22
|
-
:show,
|
23
|
-
:hide
|
24
|
-
],
|
25
|
-
|
19
|
+
:view, # view to render
|
20
|
+
:nest_name, # name as used in nest
|
21
|
+
:nest_syntax, # full nest syntax
|
22
|
+
:show, # render these views when optional
|
23
|
+
:hide # do not render these views when optional
|
24
|
+
], # show/hide can be view (Symbol), list of views (Array),
|
25
|
+
# or comma separated views (String)
|
26
26
|
heir: [
|
27
27
|
:main, # format object is page's "main" object (Boolean)
|
28
28
|
:home_view, # view for slot to return to when no view specified
|
29
|
-
:edit_structure
|
29
|
+
:edit_structure, # use a different structure for editing (Array)
|
30
|
+
:wql # contextual wql alterations for search cards (Hash)
|
30
31
|
],
|
31
32
|
both: [
|
32
33
|
:help, # cue text when editing
|
@@ -36,10 +37,10 @@ class Card
|
|
36
37
|
:editor, # inline_nests makes a form within standard content (Symbol)
|
37
38
|
:type, # set the default type of new cards
|
38
39
|
:size, # set an image size
|
39
|
-
:params, # parameters for add button. deprecate
|
40
|
+
:params, # parameters for add button. deprecate!
|
40
41
|
:items, # options for items (Hash)
|
41
42
|
:cache # change view cache behaviour
|
42
|
-
], #
|
43
|
+
], # (Symbol<:always, :standard, :never>)
|
43
44
|
none: [
|
44
45
|
:skip_perms, # do not check permissions for this view (Boolean)
|
45
46
|
:main_view # this is main view of page (Boolean)
|
@@ -136,9 +137,14 @@ class Card
|
|
136
137
|
|
137
138
|
# options to be used in data attributes of card slots (normalized options
|
138
139
|
# with standard keys)
|
140
|
+
# FIXME: what we really want is options as they were when render was called.
|
141
|
+
# normalized is wrong because it can get changed before render. live is wrong
|
142
|
+
# because they can get changed after. current solution is a compromise.
|
139
143
|
# @return [Hash]
|
140
144
|
def slot_options
|
141
|
-
normalized_options.select
|
145
|
+
normalized_options.merge(view: requested_view).select do |k, _v|
|
146
|
+
Options.all_keys.include? k
|
147
|
+
end
|
142
148
|
end
|
143
149
|
|
144
150
|
def closest_live_option key
|
@@ -175,7 +181,6 @@ class Card
|
|
175
181
|
opts
|
176
182
|
end
|
177
183
|
|
178
|
-
|
179
184
|
# typically options are already a hash. this also handles an array of
|
180
185
|
# hashes and nil.
|
181
186
|
def options_to_hash opts
|
data/mod/Modfile
CHANGED
@@ -1,38 +1,45 @@
|
|
1
|
-
|
2
1
|
module ClassMethods
|
3
|
-
|
4
2
|
# a fetch method to support the needs of the card controller.
|
5
3
|
# should be in Decko?
|
6
4
|
def controller_fetch args
|
7
|
-
|
5
|
+
card_opts = controller_fetch_opts args
|
8
6
|
if args[:action] == "create"
|
9
7
|
# FIXME: we currently need a "new" card to catch duplicates
|
10
8
|
# (otherwise save will just act like a normal update)
|
11
9
|
# We may need a "#create" instance method to handle this checking?
|
12
|
-
Card.new
|
10
|
+
Card.new card_opts
|
13
11
|
else
|
14
|
-
|
15
|
-
Card.fetch mark, look_in_trash: args[:look_in_trash], new: opts
|
12
|
+
standard_controller_fetch args, card_opts
|
16
13
|
end
|
17
14
|
end
|
18
15
|
|
19
16
|
private
|
20
17
|
|
18
|
+
def standard_controller_fetch args, card_opts
|
19
|
+
mark = args[:id] || card_opts[:name]
|
20
|
+
card = Card.fetch mark, look_in_trash: args[:look_in_trash], new: card_opts
|
21
|
+
card.assign_attributes card_opts if args[:assign] && card&.real?
|
22
|
+
card
|
23
|
+
end
|
24
|
+
|
21
25
|
def controller_fetch_opts args
|
22
|
-
opts =
|
23
|
-
# clone doesn't work for Parameters
|
24
|
-
if args[:card].respond_to?(:to_unsafe_h)
|
25
|
-
args[:card].to_unsafe_h
|
26
|
-
else
|
27
|
-
(args[:card] || {}).clone
|
28
|
-
end
|
29
|
-
# clone so that original params remain unaltered. need deeper clone?
|
26
|
+
opts = safe_card_opts args[:card]
|
30
27
|
opts[:type] ||= args[:type] if args[:type]
|
31
28
|
# for /new/:type shortcut. we should handle in routing and deprecate this
|
32
29
|
opts[:name] ||= Card::Name.url_key_to_standard(args[:id])
|
33
30
|
opts
|
34
31
|
end
|
35
32
|
|
33
|
+
def safe_card_opts card_opts
|
34
|
+
if card_opts.respond_to? :to_unsafe_h
|
35
|
+
# clone doesn't work for Parameters
|
36
|
+
card_opts.to_unsafe_h
|
37
|
+
else
|
38
|
+
# clone so that original params remain unaltered. need deeper clone?
|
39
|
+
(card_opts || {}).clone
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
36
43
|
def validate_fetch_opts! opts
|
37
44
|
return unless opts[:new] && opts[:skip_virtual]
|
38
45
|
raise Card::Error, "fetch called with new args and skip_virtual"
|
@@ -46,23 +53,30 @@ module ClassMethods
|
|
46
53
|
opts[:skip_virtual] || opts[:new].present? || opts[:skip_type_lookup]
|
47
54
|
end
|
48
55
|
|
56
|
+
# look in cache. if that doesn't work, look in database
|
57
|
+
# @return [{Card}, {True/False}] Card object and "needs_caching" ruling
|
49
58
|
def retrieve_existing mark, opts
|
50
59
|
return [nil, false] unless mark.present?
|
51
60
|
mark_type, mark_key = retrievable_mark_type_and_value mark
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# look in db if needed
|
61
|
+
if (card = retrieve_from_cache_by_mark mark_type, mark_key, opts)
|
62
|
+
# we have an acceptable card in the cache
|
63
|
+
# (and don't need to cache it again!)
|
64
|
+
[card, false]
|
65
|
+
else
|
66
|
+
# try to find the card in the database
|
59
67
|
card = retrieve_from_db mark_type, mark_key, opts[:look_in_trash]
|
60
|
-
|
68
|
+
[card, !(card.nil? || card.trash)]
|
61
69
|
end
|
70
|
+
end
|
62
71
|
|
63
|
-
|
72
|
+
def retrieve_from_cache_by_mark mark_type, mark_key, opts
|
73
|
+
card = send "retrieve_from_cache_by_#{mark_type}", mark_key, opts[:local_only]
|
74
|
+
return_cached_card?(card, opts[:look_in_trash]) ? card : nil
|
64
75
|
end
|
65
76
|
|
77
|
+
# In both the cache and the db, ids and keys are used to retrieve card data.
|
78
|
+
# This method identifies the kind of mark to use and its value
|
79
|
+
# @return [Array] first item is :id or :key, second is corresponding value
|
66
80
|
def retrievable_mark_type_and_value mark
|
67
81
|
# return mark_type and mark_value
|
68
82
|
if mark.is_a? Integer
|
@@ -72,17 +86,16 @@ module ClassMethods
|
|
72
86
|
end
|
73
87
|
end
|
74
88
|
|
75
|
-
def
|
76
|
-
return false
|
77
|
-
|
78
|
-
card.nil? || (look_in_trash && !card.trash) # card not found in cache (or trash lookup)
|
89
|
+
def return_cached_card? card, look_in_trash
|
90
|
+
return false unless card
|
91
|
+
card.real? || !look_in_trash
|
79
92
|
end
|
80
93
|
|
94
|
+
# @return [Card, nil] Card object
|
81
95
|
def retrieve_from_db mark_type, mark_key, look_in_trash=false
|
82
96
|
query = { mark_type => mark_key }
|
83
97
|
query[:trash] = false unless look_in_trash
|
84
|
-
|
85
|
-
card
|
98
|
+
Card.where(query).take
|
86
99
|
end
|
87
100
|
|
88
101
|
def standard_fetch_results card, mark, opts
|
@@ -120,7 +133,6 @@ module ClassMethods
|
|
120
133
|
return mark unless mark.name? && supercard
|
121
134
|
mark.to_name.absolute_name supercard.name
|
122
135
|
end
|
123
|
-
|
124
136
|
end
|
125
137
|
|
126
138
|
public
|
@@ -107,16 +107,12 @@ RSpec.describe Card::Format::HtmlFormat do
|
|
107
107
|
it "does not recurse" do
|
108
108
|
@layout_card.content = "Mainly {{_main|core}}"
|
109
109
|
Card::Auth.as_bot { @layout_card.save }
|
110
|
-
|
111
|
-
expect(
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
'<div class="modal-dialog"><div class="modal-content">' \
|
117
|
-
"</div></div></div>"
|
118
|
-
)
|
119
|
-
# probably better to check that it matches "Mainly" exactly twice.
|
110
|
+
rendered = @layout_card.format.render! :layout
|
111
|
+
expect(rendered).to have_tag "div#main" do
|
112
|
+
have_tag "div.code" do
|
113
|
+
have_tag("pre") { with_text "Mainly {{_main|core}}" }
|
114
|
+
end
|
115
|
+
end
|
120
116
|
end
|
121
117
|
|
122
118
|
it "handles nested _main references" do
|
@@ -125,13 +121,10 @@ RSpec.describe Card::Format::HtmlFormat do
|
|
125
121
|
@layout_card.save!
|
126
122
|
Card.create name: "outer space", content: "{{_main|name}}"
|
127
123
|
end
|
128
|
-
|
129
|
-
expect(
|
130
|
-
|
131
|
-
|
132
|
-
'<div class="modal-dialog"><div class="modal-content">' \
|
133
|
-
"</div></div></div>"
|
134
|
-
)
|
124
|
+
rendered = @main_card.format.render! :layout
|
125
|
+
expect(rendered).to have_tag "div#main" do
|
126
|
+
with_text "Joe User"
|
127
|
+
end
|
135
128
|
end
|
136
129
|
end
|
137
130
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
RSpec.describe Card::Set::All::FetchHelper do
|
4
|
+
let(:retrieve) { test_retrieve_existing }
|
5
|
+
let(:retrieve_from_trash) { test_retrieve_existing look_in_trash: true }
|
6
|
+
|
7
|
+
def test_retrieve_existing opts={}
|
8
|
+
Card.send :retrieve_existing, "A".to_name, opts
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "retrieve_existing" do
|
12
|
+
it "looks for non-cached card in database" do
|
13
|
+
expect_db_retrieval_with(:key, "a", nil) { retrieve }
|
14
|
+
end
|
15
|
+
|
16
|
+
it "doesn't look in db for cached cards(real)" do
|
17
|
+
Card.cache.write "a", Card["B"]
|
18
|
+
expect_no_db_retrieval { retrieve }
|
19
|
+
end
|
20
|
+
|
21
|
+
it "doesn't look in db for cached cards (new)" do
|
22
|
+
Card.cache.write "a", Card.new
|
23
|
+
expect_no_db_retrieval { retrieve }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "doesn't look in db for cached cards (real) if 'look_in_trash' option used" do
|
27
|
+
Card.cache.write "a", Card["B"]
|
28
|
+
expect_no_db_retrieval { retrieve_from_trash }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "looks in db for cached cards (new) if 'look_in_trash' option used" do
|
32
|
+
Card.cache.write "a", Card.new
|
33
|
+
expect_db_retrieval_with(:key, "a", true) { retrieve_from_trash }
|
34
|
+
end
|
35
|
+
|
36
|
+
def expect_no_db_retrieval
|
37
|
+
allow(Card).to receive(:retrieve_from_db)
|
38
|
+
yield
|
39
|
+
expect(Card).not_to have_received(:retrieve_from_db)
|
40
|
+
end
|
41
|
+
|
42
|
+
def expect_db_retrieval_with *args
|
43
|
+
allow(Card).to receive(:retrieve_from_db)
|
44
|
+
yield
|
45
|
+
expect(Card).to have_received(:retrieve_from_db).with(*args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|