Deep Dive

Oorian's Built-In JavaScript APIs: Control the Browser from Java

Oorian provides 19 built-in Java APIs that let you control browser features like navigation, clipboard, geolocation, notifications, speech synthesis, and more without writing a single line of JavaScript.

M. WarbleFebruary 12, 20269 min read
Oorian's Built-In JavaScript APIs: Control the Browser from Java

One of Oorian's core principles is pure Java development—you should never need to write JavaScript to build a fully interactive web application. But modern web applications often need to interact with browser APIs: reading the clipboard, getting the user's location, showing desktop notifications, or controlling navigation history.

Oorian solves this with 19 built-in JavaScript API classes that give you type-safe Java access to browser capabilities. Every API follows the same consistent patterns, dispatches results through Oorian's event system, and requires zero JavaScript knowledge to use.

The Foundation: HtmlPage and Element

Before diving into the specialized APIs, let's look at the JavaScript methods built directly into every HtmlPage and Element. These are the building blocks that the higher-level APIs are built on.

Executing JavaScript from HtmlPage

Every HtmlPage has methods for direct JavaScript execution:

// Execute a raw JavaScript statement
executeJs("console.log('Hello from the server')");

// Execute a JavaScript function with parameters
// Parameters are automatically serialized to JSON
executeJs("myFunction", param1, param2, param3);

You also have script loading with automatic deduplication:

// Load a JavaScript file (cached by browser, duplicates ignored)
loadScript("/js/my-library.js");

// Load with cache-busting timestamp
loadScript("/js/my-library.js", true);

Navigation Methods

HtmlPage provides a complete navigation API:

// Basic navigation
navigateTo("/dashboard");
navigateToReferrer();
navigateToPreviousPage();
navigateBack();
navigateBack(3);     // Go back 3 pages
navigateForward();
navigateForward(2);  // Go forward 2 pages
reload();

// Delayed navigation
navigateToAfterDelay("/timeout-page", 5000);  // Navigate after 5 seconds
reloadAfterDelay(3000);                        // Reload after 3 seconds
navigateBackAfterDelay(2000);                  // Go back after 2 seconds

// History API
historyPushState("Dashboard", "/dashboard");
historyReplaceState("Settings", "/settings");

Window Management

// Open URLs in new windows
openInNewWindow("/report");
openInNewWindow("/report", "reportWindow");
openInNewWindow("/report", "reportWindow", "width=800,height=600");

// Close a named window
closeWindow("reportWindow");

// Page unload protection (shows "Are you sure?" dialog)
blockPageUnload();    // Enable
unblockPageUnload();  // Disable

Printing

// Print the current page
print();

// Print content from a URL or another page
print(new URL("https://example.com/printable"));
print(new InvoicePage(invoiceId));

Client-Side Timers

// setTimeout equivalent - execute JS after a delay
setClientTimeout("document.title = 'Updated!'", 3000);

// setInterval equivalent - execute JS repeatedly
setClientInterval("updateClock()", 1000);

Image Preloading

// Preload images for smoother UI transitions
loadImage("/images/hero-banner.jpg");
loadImages(Arrays.asList("/images/slide1.jpg", "/images/slide2.jpg", "/images/slide3.jpg"));

Element-Level JavaScript

Individual elements also provide JavaScript interaction methods.

Scrolling

// Scroll an element to a position, top, or bottom
myPanel.scrollTo(500);
myPanel.scrollToTop();
myPanel.scrollToBottom();

Click Simulation

// Trigger a click on an element from the server
myButton.click();

DOM Updates

// Re-render and push this element to the browser
myElement.update();

// Update only attributes (more efficient)
myElement.updateAttributes();

// Full re-render from scratch
myElement.recreate();

// Refresh this element and all children
myElement.refresh();

Callbacks

The callback system lets you schedule a round-trip from server to client and back:

// Request a callback (triggers onCallback on this element)
myElement.requestCallback();
myElement.requestCallback("checkStatus");      // With an identifier
myElement.requestCallback(2000);               // After 2-second delay
myElement.requestCallback("refresh", 5000);    // Named + delayed

// Override to handle the callback
@Override
public void onCallback(String callbackId)
{
    if ("checkStatus".equals(callbackId))
    {
        refreshStatusDisplay();
    }
}

// Override to handle JavaScript return values
@Override
public void onJsReturn(String callbackId, String retval)
{
    // Handle value returned from client-side JavaScript
}

The JavaScript API Classes

Beyond the methods on HtmlPage and Element, Oorian provides 19 specialized API classes in the com.oorian.html.js package. Every API class extends JavaScriptApi and provides static methods—no instantiation required.

All APIs follow two consistent patterns:

  1. Convenience methods that automatically find the current page from the thread context
  2. Explicit methods that accept an HtmlPage parameter for use outside the normal page lifecycle

WindowApi — Window Control

Manages browser windows, dialogs, and scrolling:

// Open, close, and manage windows
WindowApi.openNew("/report");
WindowApi.openNew("/report", "Report", "width=800,height=600");
WindowApi.close("reportWindow");

// Window focus and blur
WindowApi.focus();
WindowApi.blur();

// Scroll the window
WindowApi.scrollTo(0, 500);
WindowApi.scrollBy(0, 100);

// Print
WindowApi.print();

// Show alert dialog
WindowApi.alert("Operation complete!");

// Block/unblock page unload
WindowApi.blockUnload();
WindowApi.unblockUnload();

NavigationApi — Browser Navigation and History

Full control over the browser's location and history stack:

// Navigation
NavigationApi.navigateTo("/dashboard");
NavigationApi.navigateToReferrer();
NavigationApi.back();
NavigationApi.back(3);
NavigationApi.forward();
NavigationApi.reload();

// Delayed navigation
NavigationApi.reloadAfterDelay(5000);
NavigationApi.navigateToAfterDelay("/login", 3000);
NavigationApi.backAfterDelay(2000);

// History manipulation
NavigationApi.pushState("Dashboard", "/dashboard");
NavigationApi.replaceState("Settings", "/settings");
NavigationApi.go(-2);     // Equivalent to back(2)
NavigationApi.setHash("section-3");
NavigationApi.replace("/new-url");  // Replace without history entry

ClipboardApi — Read and Write the Clipboard

// Write text to clipboard
ClipboardApi.writeText("Copied to clipboard!");

// Read clipboard text (result arrives via onJsReturn callback)
ClipboardApi.readText(myElement);

StorageApi — LocalStorage and SessionStorage

// LocalStorage
StorageApi.setLocalItem("theme", "dark");
StorageApi.getLocalItem("theme", myElement);  // Result via onJsReturn
StorageApi.removeLocalItem("theme");
StorageApi.clearLocalStorage();

// SessionStorage
StorageApi.setSessionItem("cart", cartJson);
StorageApi.getSessionItem("cart", myElement);
StorageApi.removeSessionItem("cart");
StorageApi.clearSessionStorage();

SelectionApi — Text Selection and Focus

// Select text in an element
SelectionApi.selectText(myInput);
SelectionApi.focus(myInput);
SelectionApi.selectAndFocus(myInput);

// Clear selection or select all
SelectionApi.clearSelection();
SelectionApi.selectAll();

FullscreenApi — Fullscreen Mode

// Enter fullscreen
FullscreenApi.requestFullscreen(myVideoPlayer);
FullscreenApi.requestDocumentFullscreen(myElement);

// Exit fullscreen
FullscreenApi.exitFullscreen();

// Toggle
FullscreenApi.toggleFullscreen(myElement);

TimerApi — Client and Server Timers

// Client-side timers (execute JS in the browser)
TimerApi.setClientTimeout("showToast()", 3000);
TimerApi.setClientInterval("updateClock()", 1000);

// Server-side timers (execute Java on the server)
TimerApi.setTimeout(() -> {
    statusLabel.setText("Operation complete");
    sendUpdate();
}, 5000);

TimerApi.setInterval(() -> {
    refreshDashboardData();
    sendUpdate();
}, 0, 30000);  // Every 30 seconds

ScreenApi — Screen and Device Information

Unlike the other APIs, ScreenApi reads data already collected from the client—it doesn't execute JavaScript on demand:

// Screen dimensions
int width = ScreenApi.getScreenWidth();
int height = ScreenApi.getScreenHeight();

// Window dimensions
int winWidth = ScreenApi.getWindowWidth();
int winHeight = ScreenApi.getWindowHeight();

// Device detection
boolean mobile = ScreenApi.isMobile();
boolean tablet = ScreenApi.isTablet();
boolean desktop = ScreenApi.isDesktop();
boolean highDpi = ScreenApi.isHighDpi();

// Orientation
boolean portrait = ScreenApi.isPortrait();
boolean landscape = ScreenApi.isLandscape();

// Other info
double pixelRatio = ScreenApi.getPixelRatio();
String userAgent = ScreenApi.getUserAgent();
int utcOffset = ScreenApi.getUtcOffset();
String ip = ScreenApi.getIpAddress();

GeolocationApi — GPS and Location

public class MapPage extends HtmlPage implements GeolocationListener
{
    @Override
    protected void createBody(Body body)
    {
        body.registerListener(this, GeolocationEvent.class);
        body.registerListener(this, GeolocationErrorEvent.class);

        // One-time position request
        GeolocationApi.getCurrentPosition(body);

        // Or continuous tracking
        String watchId = GeolocationApi.watchPosition(body);

        // Stop tracking later
        GeolocationApi.clearWatch(watchId);
    }

    @Override
    public void onEvent(GeolocationEvent event)
    {
        double lat = event.getLatitude();
        double lon = event.getLongitude();
        updateMap(lat, lon);
    }

    @Override
    public void onEvent(GeolocationErrorEvent event)
    {
        showError(event.getMessage());
    }
}

NotificationApi — Desktop Notifications

// Request permission first
NotificationApi.requestPermission(body);

// Show notifications
NotificationApi.show(body, "New Message");
NotificationApi.show(body, "New Message", "You have 3 unread messages");

// With options
NotificationOptions options = new NotificationOptions();
options.setBody("You have 3 unread messages");
options.setIcon("/images/notification-icon.png");
NotificationApi.show(body, "New Message", options);

// Close all notifications
NotificationApi.closeAll();

SpeechApi — Text-to-Speech and Speech Recognition

// Text-to-Speech
SpeechApi.speak("Welcome to the application");
SpeechApi.speak("Bienvenue", "fr-FR", 1.0f, 1.0f);

// Speech control
SpeechApi.pauseSpeech();
SpeechApi.resumeSpeech();
SpeechApi.cancelSpeech();

// Speech Recognition (results arrive via SpeechResultEvent)
SpeechApi.startRecognition(body);
SpeechApi.startRecognition(body, "en-US");
SpeechApi.startRecognition(body, "en-US", true);  // Continuous mode
SpeechApi.stopRecognition();

ShareApi — Native Sharing (Mobile)

// Share content using the device's native share sheet
ShareApi.shareText(body, "Check out this framework!");
ShareApi.shareUrl(body, "https://oorian.com");
ShareApi.shareUrl(body, "Oorian Framework", "https://oorian.com");
ShareApi.share(body, "Check out Oorian!", "Oorian Framework", "https://oorian.com");

MediaDevicesApi — Camera and Microphone

// Enumerate available devices
MediaDevicesApi.enumerateDevices(body);

// Request access to specific devices
MediaDevicesApi.requestCameraAccess(body);
MediaDevicesApi.requestMicrophoneAccess(body);
MediaDevicesApi.requestFullAccess(body);  // Both camera and microphone

// Custom request
MediaDevicesApi.getUserMedia(body, true, true);  // audio, video

PermissionsApi — Query Browser Permissions

// Query individual permissions
PermissionsApi.queryGeolocation(body);
PermissionsApi.queryNotifications(body);
PermissionsApi.queryCamera(body);
PermissionsApi.queryMicrophone(body);

// Query by name
PermissionsApi.query(body, PermissionsApi.PERSISTENT_STORAGE);

// Query multiple at once
PermissionsApi.queryAll(body, "geolocation", "notifications", "camera");

NetworkApi — Online/Offline Detection

// Monitor network status changes
NetworkApi.startListening(body);

// Check current status
NetworkApi.checkStatus(body);

// Stop listening
NetworkApi.stopListening();

VisibilityApi — Tab Visibility

// Know when the user switches tabs or minimizes the browser
VisibilityApi.startListening(body);
VisibilityApi.stopListening();

VibrationApi — Haptic Feedback

// Basic vibration
VibrationApi.vibrate(200);                     // 200ms
VibrationApi.vibrate(100, 50, 100, 50, 100);  // Custom pattern

// Predefined patterns
VibrationApi.tap();        // Quick tap
VibrationApi.doubleTap();  // Double tap
VibrationApi.success();    // Success feedback
VibrationApi.error();      // Error feedback
VibrationApi.warning();    // Warning feedback

// Cancel
VibrationApi.cancel();

WakeLockApi — Prevent Screen Dimming

// Keep the screen on (useful for video players, presentations, navigation)
WakeLockApi.request(body);

// Release when done
WakeLockApi.release(body);

The Event-Driven Pattern

Most of the browser APIs are asynchronous by nature—you request something from the browser and the result comes back later. Oorian handles this with its standard event system. The pattern is always the same:

  1. Register a listener for the event type on an element (usually the page body)
  2. Call the API method, passing that element as the callback target
  3. Handle the result in your listener's onEvent method
// 1. Implement the listener interface
public class MyPage extends HtmlPage implements NetworkListener
{
    @Override
    protected void createBody(Body body)
    {
        // 2. Register for events
        body.registerListener(this, NetworkStatusEvent.class);

        // 3. Call the API
        NetworkApi.startListening(body);
    }

    @Override
    public void onEvent(NetworkStatusEvent event)
    {
        // 4. Handle the result
        if (event.isOnline())
        {
            statusLabel.setText("Connected");
        }
        else
        {
            statusLabel.setText("Offline - changes will sync when reconnected");
        }
    }
}

This pattern keeps everything type-safe and consistent. There are no magic strings, no callback functions, no promises to chain—just standard Java interfaces that your IDE understands completely.

Complete API Reference

Here's a quick reference of all 19 API classes and what they do:

API Class Purpose Events
WindowApiWindow management, alerts, scrolling, printNone
NavigationApiURL navigation, history, back/forwardNone
TimerApiClient and server timersNone
ScreenApiScreen size, device type, orientationNone (reads ClientProfile)
SelectionApiText selection and focusNone
ClipboardApiRead/write clipboardVia onJsReturn
StorageApiLocalStorage and SessionStorageVia onJsReturn
FullscreenApiFullscreen mode controlNone
GeolocationApiGPS position trackingGeolocationEvent
NotificationApiDesktop notificationsNotificationClickEvent
SpeechApiText-to-speech and recognitionSpeechResultEvent
ShareApiNative sharing (mobile)ShareSuccessEvent
MediaDevicesApiCamera/microphone accessMediaDevicesEvent
PermissionsApiBrowser permission statusPermissionStatusEvent
NetworkApiOnline/offline detectionNetworkStatusEvent
VisibilityApiTab visibility changesVisibilityChangeEvent
VibrationApiHaptic feedback patternsNone
WakeLockApiPrevent screen dimmingWakeLockEvent

Conclusion

Oorian's JavaScript API layer is one of the framework's most powerful features. It gives you access to the full range of modern browser capabilities—from geolocation to speech recognition to haptic feedback—through consistent, type-safe Java interfaces. No JavaScript required.

Every API follows the same patterns: static methods for simplicity, event-driven results for async operations, and both convenience and explicit-page overloads for flexibility. Once you learn the pattern with one API, you know them all.

This is what "Pure Java Development" really means in Oorian. It's not just about HTML generation—it's about giving Java developers full, first-class access to everything the browser can do.

Related Articles

Deep Dive

Oorian Add-Ons: Server-Side Building Blocks for Real Applications

February 17, 2026
Deep Dive

CSS Styling in Oorian

February 10, 2026
Deep Dive

LaunchPad: Self-Contained Deployment for Oorian Applications

February 5, 2026