big filter refactoring

This commit is contained in:
Manuel Simon Hirsig
2016-08-02 00:25:13 +02:00
parent 67a0179a2f
commit a11a4e891c
3 changed files with 96 additions and 51 deletions
+1 -1
View File
@@ -95,7 +95,7 @@ do
end
function public.on_load()
public.version = '3.5.3'
public.version = '3.6.0'
public.bids_loaded = false
public.current_owner_page = nil
public.last_owner_page_requested = nil
+21 -27
View File
@@ -785,6 +785,7 @@ function private.initialize_filter_dropdown()
m.filter_input:Hide()
else
m.filter_input:Show()
m.filter_input:SetFocus()
end
end
@@ -797,38 +798,31 @@ function private.initialize_filter_dropdown()
end
end
do
local stack = {}
function private.import_query_string()
function private.add_post_filter()
local name = UIDropDownMenu_GetSelectedValue(m.filter_dropdown) or ''
local input = m.filter_input:GetText()
if Aux.safe(Aux.filter.filters[name]).validator(input)/true then
local filter = name
if Aux.safe(Aux.filter.filters)[name].input_type ~= '' then
filter = filter..'/'..input
end
end
local filters = m.filter_display:GetText() or ''
if filters ~= '' then
filters = filters..'|n'
end
for _=1,getn(stack) do
filters = filters..' '
end
m.filter_display:SetText(filters..filter)
function private.export_query_string()
end
private.post_query = {}
function private.add_post_filter()
local name = UIDropDownMenu_GetSelectedValue(m.filter_dropdown)
if name then
local filter = name
if Aux.filter.filters[name] and Aux.filter.filters[name].input_type ~= '' then
filter = filter..'/'..m.filter_input:GetText()
end
local components, error, suggestions = Aux.filter.parse_query_string(filter)
if components then
tinsert(m.post_query, components[1])
m.filter_display:SetText(Aux.filter.indented_post_query_string(m.post_query))
m.filter_input:SetText('')
m.filter_input:ClearFocus()
if Aux.util.set('and', 'or')[filter] then
tinsert(stack, 2)
else
local top = tremove(stack)
if top and top > 1 then
tinsert(stack, top - 1)
end
end
end
end
end
+74 -23
View File
@@ -330,18 +330,16 @@ function private.parse_parameter(input_type, str)
end
end
function private.parse_query_string(str)
function public.parse_query_string(str)
local components = { blizzard = {}, post = {} }
local blizzard_filter_parser = m.blizzard_filter_parser()
local parts = Aux.util.map(Aux.util.split(str, '/'), function(part) return strlower(Aux.util.trim(part)) end)
local polish_notation_counter = 0
local i = 1
while parts[i] do
local op, arity = m.operator(parts[i])
if op then
tinsert(components.post, {'operator', op, arity})
polish_notation_counter = polish_notation_counter + (arity or 1) - 1
elseif m.filters[parts[i]] then
local input_type = m.filters[parts[i]].input_type
if input_type ~= '' then
@@ -357,7 +355,6 @@ function private.parse_query_string(str)
else
tinsert(components.post, {'filter', parts[i]})
end
polish_notation_counter = polish_notation_counter - 1
else
local component, error = blizzard_filter_parser(parts[i], i == 1)
if component then
@@ -366,7 +363,6 @@ function private.parse_query_string(str)
return nil, error
elseif parts[i] ~= '' then
tinsert(components.post, {'filter', 'tooltip', parts[i]})
polish_notation_counter = polish_notation_counter - 1
else
return nil, 'Empty modifier'
end
@@ -374,17 +370,6 @@ function private.parse_query_string(str)
i = i + 1
end
if polish_notation_counter > 0 then
local suggestions = {}
for filter, _ in m.filters do
tinsert(suggestions, strlower(filter))
end
tinsert(suggestions, 'and')
tinsert(suggestions, 'or')
tinsert(suggestions, 'not')
return nil, 'Malformed expression', i > getn(parts) and suggestions
end
return components
end
@@ -395,10 +380,31 @@ function public.query(query_string)
return nil, suggestions or {}, error
end
local polish_notation_counter = 0
for _, component in components.post do
if component[1] == 'operator' then
polish_notation_counter = max(polish_notation_counter, 1)
polish_notation_counter = polish_notation_counter + (component[2] or 1) - 1
elseif component[1] == 'filter' then
polish_notation_counter = polish_notation_counter - 1
end
end
if polish_notation_counter > 0 then
local suggestions = {}
for filter, _ in m.filters do
tinsert(suggestions, strlower(filter))
end
tinsert(suggestions, 'and')
tinsert(suggestions, 'or')
tinsert(suggestions, 'not')
return nil, {}, 'Malformed expression' --, i > getn(parts) and suggestions
end
return {
blizzard_query = m.blizzard_query(components),
validator = m.validator(components),
prettified = m.prettified(components),
prettified = m.prettified_query_string(components),
}, m.suggestions(components)
end
@@ -495,7 +501,44 @@ function private.suggestions(components)
return suggestions
end
function private.prettified(components)
function public.indented_post_query_string(components)
local stack = {}
local str = ''
for _, component in components.post do
if str ~= '' then
str = str..'|n'
end
for _=1,getn(stack) do
str = str..' '
end
if component[1] == 'operator' and component[2] then
local suffix = ''
if not component[3] then
suffix = '*'
elseif component[3] > 2 then
suffix = component[3]
end
str = str..'|cffffff00'..component[2]..suffix..'|r'
tinsert(stack, component[3])
elseif component[1] == 'filter' then
str = str..'|cffffff00'..component[2]..'|r'
if component[3] then
str = str..': '..'|cffff9218'..component[3]..'|r'
end
local top = tremove(stack)
if top and top > 1 then
tinsert(stack, top - 1)
end
end
end
return str
end
function private.prettified_query_string(components)
local prettified = m.query_builder()
local blizzard_filters = {}
@@ -579,8 +622,10 @@ end
function private.validator(components)
local validators = {}
for _, filter in Aux.util.filter(components.post, function(component) return component[1] == 'filter' end) do
validators[filter[2]] = m.filters[filter[2]].validator(m.parse_parameter(m.filters[filter[2]].input_type, filter[3]))
for i, component in components.post do
if component[1] == 'filter' then
validators[i] = m.filters[component[2]].validator(m.parse_parameter(m.filters[component[2]].input_type, component[3]))
end
end
return function(record)
@@ -606,16 +651,22 @@ function private.validator(components)
tinsert(stack, Aux.util.any(args, Aux.util.id))
end
elseif type == 'filter' then
tinsert(stack, validators[name](record) and true or false)
tinsert(stack, validators[i](record) and true or false)
end
end
return Aux.util.all(stack, Aux.util.id)
end
end
function private.query_builder()
local filter = ''
function public.query_builder(str)
local filter = str or ''
return {
appended = function(part)
return m.query_builder(filter == '' and part or filter..'/'..part)
end,
prepended = function(part)
return m.query_builder(filter == '' and part or part..'/'..filter)
end,
append = function(part)
filter = filter == '' and part or filter..'/'..part
end,