@@ -414,15 +414,7 @@ register_theme_elements <- function(..., element_tree = NULL, complete = TRUE) {
414414 t <- theme(... , complete = complete )
415415 ggplot_global $ theme_default <- ggplot_global $ theme_default %+ replace % t
416416
417- # Check element tree, prevent elements from being their own parent (#6162)
418- bad_parent <- unlist(Map(
419- function (name , el ) any(name %in% el $ inherit ),
420- name = names(element_tree ), el = element_tree
421- ))
422- if (any(bad_parent )) {
423- bad_parent <- names(element_tree )[bad_parent ]
424- cli :: cli_abort(" Invalid parent: {.and {.val {bad_parent}}}." )
425- }
417+ check_element_tree(element_tree )
426418
427419 # Merge element trees
428420 ggplot_global $ element_tree <- defaults(element_tree , ggplot_global $ element_tree )
@@ -469,6 +461,43 @@ get_element_tree <- function() {
469461 ggplot_global $ element_tree
470462}
471463
464+ check_element_tree <- function (x , arg = caller_arg(x ), call = caller_env()) {
465+ check_object(x , is_bare_list , " a bare {.cls list}" , arg = arg , call = call )
466+ if (length(x ) < 1 ) {
467+ return (invisible (NULL ))
468+ }
469+
470+ if (! is_named(x )) {
471+ cli :: cli_abort(" {.arg {arg}} must have names." , call = call )
472+ }
473+
474+ # All elements should be constructed with `el_def()`
475+ fields <- names(el_def())
476+ bad_fields <- ! vapply(x , function (el ) all(fields %in% names(el )), logical (1 ))
477+ if (any(bad_fields )) {
478+ bad_fields <- names(x )[bad_fields ]
479+ cli :: cli_abort(
480+ c(" {.arg {arg}} must have elements constructed with {.fn el_def}." ,
481+ i = " Invalid structure: {.and {.val {bad_fields}}}" ),
482+ call = call
483+ )
484+ }
485+
486+ # Check element tree, prevent elements from being their own parent (#6162)
487+ bad_parent <- unlist(Map(
488+ function (name , el ) any(name %in% el $ inherit ),
489+ name = names(x ), el = x
490+ ))
491+ if (any(bad_parent )) {
492+ bad_parent <- names(x )[bad_parent ]
493+ cli :: cli_abort(
494+ " Invalid parent in {.arg {arg}}: {.and {.val {bad_parent}}}." ,
495+ call = call
496+ )
497+ }
498+ invisible (NULL )
499+ }
500+
472501# ' @rdname register_theme_elements
473502# ' @details
474503# ' The function `el_def()` is used to define new or modified element types and
0 commit comments