Skip to content

Commit 2a93c81

Browse files
committed
Merge branch 'dev' into json3
2 parents c021c17 + 4190e5d commit 2a93c81

File tree

13 files changed

+202
-126
lines changed

13 files changed

+202
-126
lines changed

.circleci/config.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: 2
33
jobs:
44

55
test:
6-
working_directory: ~/dashjl
6+
working_directory: ~/dashjl
77
docker:
88
- image: plotly/julia:ci
99
auth:
@@ -30,15 +30,15 @@ jobs:
3030
- run:
3131
name: 🔎 Unit tests
3232
command: |
33-
julia test/ci_prepare.jl
33+
julia test/ci_prepare.jl
3434
3535
- run:
3636
name: ⚙️ Integration tests
3737
command: |
3838
python -m venv venv
3939
. venv/bin/activate
4040
git clone --depth 1 https://github.com/plotly/dash.git -b dev dash-main
41-
cd dash-main && pip install -e .[dev,testing] --progress-bar off && cd ~/dashjl
41+
cd dash-main && pip install -e .[dev,testing] --progress-bar off && cd ~/dashjl
4242
export PATH=$PATH:/home/circleci/.local/bin/
4343
pytest --headless --nopercyfinalize --junitxml=test-reports/dashjl.xml --percy-assets=test/assets/ test/integration/
4444
- store_artifacts:
@@ -51,7 +51,6 @@ jobs:
5151
- run:
5252
name: 🦔 percy finalize
5353
command: npx percy finalize --all
54-
when: on_fail
5554

5655
workflows:
5756
version: 2

src/app/callbacks.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,21 +165,11 @@ function check_callback(func, app::DashApp, deps::CallbackDeps)
165165
isempty(deps.output) && error("The callback method requires that one or more properly formatted outputs are passed.")
166166
isempty(deps.input) && error("The callback method requires that one or more properly formatted inputs are passed.")
167167

168-
!check_unique(deps.output) && error("One or more callback outputs have been duplicated; please confirm that all outputs are unique.")
169-
170-
for out in deps.output
171-
if any(x->out in x.dependencies.output, values(app.callbacks))
172-
error("output \"$(out)\" already registered")
173-
end
174-
end
175168

176169
args_count = length(deps.state) + length(deps.input)
177170

178171
check_callback_func(func, args_count)
179172

180-
for id_prop in deps.input
181-
id_prop in deps.output && error("Circular input and output arguments were found. Please verify that callback outputs are not also input arguments.")
182-
end
183173
end
184174

185175
function check_callback_func(func::Function, args_count)

src/favicon.ico

15 KB
Binary file not shown.

src/handler/callback_context.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using .Contexts
22
const CallbackContextItems = Union{Nothing, Vector{NamedTuple}}
33
const TriggeredParam = NamedTuple{(:prop_id, :value)}
4+
5+
46
mutable struct CallbackContext
57
response::HTTP.Response
68
inputs::Dict{String, Any}

src/handler/index_page.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,30 @@ end
9999

100100
renderer_html() = """<script id="_dash-renderer" type="application/javascript">var renderer = new DashRenderer();</script>"""
101101

102-
favicon_html(app::DashApp) = ""
102+
function favicon_html(app::DashApp, resources::ApplicationResources)
103+
favicon_url = if !isnothing(resources.favicon)
104+
asset_path(app, resources.favicon.path)
105+
else
106+
"$(get_setting(app, :requests_pathname_prefix))_favicon.ico?v=$(build_info().dash_version)"
107+
end
108+
return format_tag(
109+
"link",
110+
Dict(
111+
"rel" => "icon",
112+
"type" => "image/x-icon",
113+
"href" => favicon_url
114+
),
115+
opened = true
116+
)
117+
end
103118

104119

105120
function index_page(app::DashApp, resources::ApplicationResources)
106121

107122
result = interpolate_string(app.index_string,
108123
metas = metas_html(app),
109124
title = app.title,
110-
favicon = favicon_html(app),
125+
favicon = favicon_html(app, resources),
111126
css = css_html(app, resources),
112127
app_entry = app_entry_html(),
113128
config = config_html(app),

src/handler/make_handler.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ include("processors/index.jl")
55
include("processors/layout.jl")
66
include("processors/reload_hash.jl")
77
include("processors/resource.jl")
8+
include("processors/default_favicon.jl")
89

910
function start_reload_poll(state::HandlerState)
1011
folders = Set{String}()
@@ -124,6 +125,7 @@ function make_handler(app::DashApp, registry::ResourcesRegistry; check_layout =
124125
add_route!(process_layout, router, "$(prefix)_dash-layout")
125126
add_route!(process_dependencies, router, "$(prefix)_dash-dependencies")
126127
add_route!(process_reload_hash, router, "$(prefix)_reload-hash")
128+
add_route!(process_default_favicon, router, "$(prefix)_favicon.ico")
127129
add_route!(process_resource, router, "$(prefix)_dash-component-suites/<namespace>/<path>")
128130
add_route!(process_assets, router, "$(prefix)$(assets_url_path)/<file_path>")
129131
add_route!(process_callback, router, "POST", "$(prefix)_dash-update-component")

src/handler/processors/callback.jl

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
function split_single_callback_id(callback_id::AbstractString)
2+
parts = rsplit(callback_id, ".")
3+
return (id = parts[1], property = parts[2])
4+
end
15
function split_callback_id(callback_id::AbstractString)
26
if startswith(callback_id, "..")
37
result = []
4-
append!.(Ref(result), split_callback_id.(split(callback_id[3:end-2], "...", keepempty = false)))
8+
push!.(Ref(result), split_single_callback_id.(split(callback_id[3:end-2], "...", keepempty = false)))
59
return result
610
end
7-
parts = rsplit(callback_id, ".")
8-
return [(id = parts[1], property = parts[2])]
11+
return split_single_callback_id(callback_id)
912
end
1013

1114
input_to_arg(input) = get(input, :value, nothing)
@@ -51,8 +54,7 @@ function process_callback_call(app, callback_id, outputs, inputs, state)
5154
return Dict(:response=>response, :multi=>true)
5255
end
5356

54-
outputs_to_vector(out::AbstractVector) = out
55-
outputs_to_vector(out) = [out]
57+
outputs_to_vector(out, is_multi) = is_multi ? out : [out]
5658

5759
function process_callback(request::HTTP.Request, state::HandlerState)
5860
app = state.app
@@ -62,11 +64,14 @@ function process_callback(request::HTTP.Request, state::HandlerState)
6264
inputs = get(params, :inputs, [])
6365
state = get(params, :state, [])
6466
output = Symbol(params[:output])
65-
outputs_list = outputs_to_vector(get(params, :outputs, split_callback_id(params[:output])))
66-
changedProps = get(params, :changedPropIds, [])
67-
context = CallbackContext(response, outputs_list, inputs, state, changedProps)
6867

6968
try
69+
is_multi = is_multi_out(app.callbacks[output])
70+
outputs_list = outputs_to_vector(
71+
get(params, :outputs, split_callback_id(params[:output])),
72+
is_multi)
73+
changedProps = get(params, :changedPropIds, [])
74+
context = CallbackContext(response, outputs_list, inputs, state, changedProps)
7075
cb_result = with_callback_context(context) do
7176
process_callback_call(app, output, outputs_list, inputs, state)
7277
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function process_default_favicon(request::HTTP.Request, state::HandlerState)
2+
ico_contents = read(
3+
joinpath(ROOT_PATH, "src", "favicon.ico")
4+
)
5+
return HTTP.Response(
6+
200,
7+
["Content-Type" => "image/x-icon"],
8+
body = ico_contents
9+
)
10+
end

src/resources/application.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@ struct ApplicationResources
2727
files ::Dict{String, NamespaceFiles}
2828
css ::Vector{AppResource}
2929
js ::Vector{AppResource}
30-
favicon ::Union{Nothing, String}
30+
favicon ::Union{Nothing, AppAssetResource}
3131
ApplicationResources(files, css, js, favicon) = new(files, css, js, favicon)
3232
end
3333

3434

3535
function ApplicationResources(app::DashApp, registry::ResourcesRegistry)
3636
css = AppResource[]
3737
js = AppResource[]
38-
favicon::Union{Nothing, String} = nothing
38+
favicon::Union{Nothing, AppResource} = nothing
3939
files = Dict{String, NamespaceFiles}()
40-
40+
4141
serve_locally = get_setting(app, :serve_locally)
4242
assets_external_path = get_setting(app, :assets_external_path)
4343
dev = get_devsetting(app, :serve_dev_bundles)
4444
eager_loading = get_setting(app, :eager_loading)
45-
45+
4646
append_pkg = function(pkg)
4747
append!(css,
4848
_convert_resource_pkg(pkg, :css, dev = dev, serve_locally = serve_locally, eager_loading = eager_loading)
@@ -58,10 +58,10 @@ function ApplicationResources(app::DashApp, registry::ResourcesRegistry)
5858

5959
append_pkg(get_dash_dependencies(registry, get_devsetting(app, :props_check)))
6060

61-
append!(css,
61+
append!(css,
6262
_convert_external.(get_setting(app, :external_stylesheets))
6363
)
64-
append!(js,
64+
append!(js,
6565
_convert_external.(get_setting(app, :external_scripts))
6666
)
6767

@@ -72,7 +72,7 @@ function ApplicationResources(app::DashApp, registry::ResourcesRegistry)
7272
elseif type == :css
7373
push!(css, asset_resource(url, modified))
7474
elseif type == :favicon
75-
favicon = url
75+
favicon = AppAssetResource(url, modified)
7676
end
7777
end
7878
end
@@ -113,7 +113,7 @@ function walk_assets(callback, app::DashApp)
113113
assets_filter = isempty(assets_ignore) ?
114114
(f) -> true :
115115
(f) -> !occursin(assets_regex, f)
116-
116+
117117
assets_path = get_assets_path(app)
118118
if get_setting(app, :include_assets_files) && isdir(assets_path)
119119
for (base, dirs, files) in walkdir(assets_path)
@@ -181,9 +181,9 @@ function _convert_resource_pkg(pkg::ResourcePkg, type::Symbol; dev, serve_locall
181181
ts = ispath(pkg.path) ? trunc(Int64, stat(pkg.path).mtime) : 0
182182
for resource in iterator
183183
append!(
184-
result,
184+
result,
185185
_convert_resource(
186-
resource,
186+
resource,
187187
namespace = pkg.namespace,
188188
version = pkg.version,
189189
ts = ts,

0 commit comments

Comments
 (0)