NAME

Chandra::App - High-level application wrapper for Chandra

SYNOPSIS

use Chandra::App;

my $app = Chandra::App->new(
    title  => 'My App',
    width  => 800,
    height => 600,
);

$app->bind('greet', sub {
    my ($name) = @_;
    return "Hello, $name!";
});

$app->set_content('<h1>Hello World</h1><button onclick="window.chandra.invoke(\'greet\',[\'World\']).then(r=>document.title=r)">Greet</button>');

$app->run;

# --- Routing Example ---

use Chandra::Element;

my $spa = Chandra::App->new(title => 'My SPA', width => 800, height => 600);

$spa->layout(sub {
    my ($body) = @_;
    Chandra::Element->new({
        tag => 'div',
        children => [
            {
                tag => 'nav',
                children => [
                    { tag => 'a', href => '/',      data => 'Home' },
                    { tag => 'a', href => '/about', data => ' | About' },
                ]
            },
            { tag => 'div', id => 'chandra-content', raw => $body },
        ],
    });
});

$spa->route('/' => sub {
    Chandra::Element->new(
        tag => 'div',
        children => [
            { tag => 'h1', data => 'Home' },
            { tag => 'p',  data => 'Welcome!' },
        ],
    );
});

$spa->route('/about' => sub {
    Chandra::Element->new(
        tag => 'div',
        children => [
            { tag => 'h1', data => 'About' },
            { tag => 'p',  data => 'Info here' },
        ],
    );
});

$spa->route('/user/:id' => sub {
    my (%params) = @_;
    Chandra::Element->new(
        tag => 'h1', data => "User $params{id}",
    );
});

$spa->not_found(sub {
    Chandra::Element->new(tag => 'h1', data => '404 - Not Found');
});

$spa->run;

DESCRIPTION

Chandra::App provides a clean, high-level OO interface on top of the XS-backed Chandra module. It manages the webview lifecycle and provides convenience methods for setting content, updating the DOM, and running JavaScript.

METHODS

new(%args)

Create a new application. Accepts all the same options as Chandra->new: title, url, width, height, resizable, debug.

run()

Initialize the webview, inject any set_content HTML, and enter the event loop. Blocks until the window is closed.

bind($name, $coderef)

Register a Perl subroutine callable from JavaScript via window.chandra.invoke($name, [args]).

set_content($html_or_element)

Set the page content. Accepts a plain HTML string or any object that responds to render() (e.g., a future Chandra::Element).

update($selector, $html_or_element)

Replace the innerHTML of the element matching $selector.

eval($js)

Execute JavaScript in the webview.

dispatch_eval($js)

Deferred JavaScript evaluation, safe to call from within Perl callbacks.

set_title($title)

Change the window title.

alert($message)

Show a JavaScript alert dialog.

devtools()

Return the Chandra::DevTools instance for this application. Creates and enables it on first call. The DevTools panel can be toggled in the browser with F12 or Ctrl+Shift+I.

on_error($coderef)

Register a callback invoked when an error is captured by Chandra::Error. The callback receives a hashref with message, context, trace, and time.

watch($path, $coderef)

Watch a file or directory for changes. When modifications are detected the callback is invoked with an arrayref of changed paths. Activates Chandra::HotReload polling inside run().

refresh()

Re-inject the current set_content HTML and re-apply DevTools. Useful inside hot-reload callbacks.

dialog()

Return the Chandra::Dialog instance for opening native file and alert dialogs.

protocol()

Return the Chandra::Protocol instance for registering custom URL scheme handlers (e.g. myapp://path).

inject_css($css)

Inject a CSS stylesheet into the current page.

fullscreen($enable)

Enter or leave fullscreen mode. Pass 1 to enable, 0 to disable.

set_color($r, $g, $b, $a)

Set the webview background colour as RGBA (0-255). Alpha defaults to 255.

terminate()

Signal the event loop to stop.

route($path, $coderef)

Register a route. When the application is in routing mode (at least one route registered), run() renders the initial route instead of using set_content. The coderef should return an HTML string or an object with a render() method.

$app->route('/' => sub { '<h1>Home</h1>' });

Route parameters are supported with :param placeholders:

$app->route('/user/:id' => sub {
    my (%params) = @_;
    "<h1>User $params{id}</h1>";
});

layout($coderef)

Set a layout wrapper applied to every route. The coderef receives the rendered page body as its argument and must return the full HTML. Include an element with id="chandra-content" for partial updates:

$app->layout(sub {
    my ($body) = @_;
    "<nav>...</nav><div id='chandra-content'>$body</div>";
});

Navigate to a registered route. If the application is running, the content is updated in-place and a history entry is pushed.

not_found($coderef)

Set a custom 404 handler for unmatched routes. Defaults to a simple <h1>404 - Not Found</h1> page.

webview()

Access the underlying Chandra XS object.

init() / loop($blocking) / exit()

Low-level lifecycle methods for manual event loop control.

SEE ALSO

Chandra, Chandra::Element, Chandra::Bind, Chandra::DevTools, Chandra::HotReload, Chandra::Dialog, Chandra::Protocol, Chandra::Socket::Hub, Chandra::Socket::Client