CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tarojs--runtime

Cross-platform runtime for Taro framework providing DOM/BOM polyfills and mini-program bridge functionality

Pending
Overview
Eval results
Files

bom.mddocs/

Browser Object Model (BOM) APIs

Complete browser API polyfills that enable web-like development on mini-program platforms. The BOM implementation provides familiar browser objects including document, window, history, location, and navigation APIs.

Overview

The BOM module creates a standardized browser environment across all platforms by implementing:

  • Document API: DOM document interface with element creation and selection
  • Window API: Global window object with event handling and timing functions
  • History API: Browser navigation history with state management
  • Location API: URL manipulation and navigation control
  • Navigator API: Browser/platform information access
  • URL APIs: URL parsing, manipulation and query parameter handling
  • Animation APIs: RequestAnimationFrame for smooth animations

Document API

document

import { document, TaroDocument } from '@tarojs/runtime'

interface TaroDocument extends TaroElement {
  // Element creation
  createElement(tagName: string): TaroElement
  createTextNode(data: string): TaroText
  createComment(data: string): TaroText
  
  // Element selection
  getElementById(id: string): TaroElement | null
  querySelector(selectors: string): TaroElement | null
  querySelectorAll(selectors: string): TaroElement[]
  
  // Properties
  documentElement: TaroElement  // <html> element
  head: TaroElement            // <head> element  
  body: TaroElement            // <body> element
  
  // Event handling
  addEventListener(type: string, handler: EventListener): void
  removeEventListener(type: string, handler: EventListener): void
}

The document creates a standard HTML structure:

<html>
  <head/>
  <body>
    <container>
      <app/>
    </container>
  </body>
</html>

Usage Examples

// Create elements
const view = document.createElement('view')
const text = document.createTextNode('Hello World')
view.appendChild(text)

// Find elements
const app = document.getElementById('app')
const container = document.querySelector('.container')
const views = document.querySelectorAll('view')

// Modify document
document.body.appendChild(view)
document.documentElement.className = 'theme-dark'

Window API

window

import { window, TaroWindow } from '@tarojs/runtime'

interface TaroWindow extends Events {
  // Navigation objects
  navigator: Navigator
  location: TaroLocation
  history: TaroHistory
  
  // Timing functions
  setTimeout(handler: TimerHandler, timeout?: number, ...args: any[]): number
  clearTimeout(handle?: number): void
  setInterval(handler: TimerHandler, timeout?: number, ...args: any[]): number
  clearInterval(handle?: number): void
  
  // Animation
  requestAnimationFrame(callback: FrameRequestCallback): number
  cancelAnimationFrame(handle: number): void
  
  // Styles
  getComputedStyle(element: Element, pseudoElt?: string | null): CSSStyleDeclaration
  
  // Standard objects
  Date: DateConstructor
  XMLHttpRequest: any
  
  // Event handling (inherited from Events)
  addEventListener(type: string, handler: EventListener): void
  removeEventListener(type: string, handler: EventListener): void
  
  // Context management (internal)
  CONTEXT_ACTIONS: typeof CONTEXT_ACTIONS
}

enum CONTEXT_ACTIONS {
  INIT = '0',    // Initialize new page context
  RESTORE = '1', // Restore existing context  
  RECOVER = '2', // Recover from cached context
  DESTORY = '3'  // Destroy context on page unload
}

Usage Examples

// Timer functions
const timerId = window.setTimeout(() => {
  console.log('Delayed execution')
}, 1000)

const intervalId = window.setInterval(() => {
  console.log('Periodic execution')  
}, 500)

window.clearTimeout(timerId)
window.clearInterval(intervalId)

// Animation frame
window.requestAnimationFrame((timestamp) => {
  // Animation logic
  console.log('Frame at:', timestamp)
})

// Event handling
window.addEventListener('resize', () => {
  console.log('Window resized')
})

// Get computed styles
const styles = window.getComputedStyle(element)
console.log(styles.color, styles.fontSize)

History API

History

import { History, TaroHistory } from '@tarojs/runtime'

interface TaroHistory extends Events {
  // Properties
  readonly length: number
  readonly state: any
  
  // Navigation methods
  back(): void
  forward(): void
  go(delta?: number): void
  
  // State management
  pushState(stateObj: any, title: string, url?: string | null): void
  replaceState(stateObj: any, title: string, url?: string | null): void
  
  // Event handling
  addEventListener(type: 'popstate', handler: (event: PopStateEvent) => void): void
  removeEventListener(type: 'popstate', handler: (event: PopStateEvent) => void): void
}

// Global history instance
const history: TaroHistory

Key Features

  • Multi-page Context: Maintains separate history stacks for different page contexts
  • State Caching: Preserves navigation state across page switches
  • Event Integration: Fires popstate events for navigation changes
  • URL Validation: Validates URLs and handles navigation edge cases

Usage Examples

// Navigation
history.back()           // Go back one step
history.forward()        // Go forward one step  
history.go(-2)          // Go back 2 steps
history.go(1)           // Go forward 1 step

// State management
history.pushState({ page: 1 }, 'Page 1', '/page1')
history.replaceState({ page: 2 }, 'Page 2', '/page2')

// Listen for navigation
history.addEventListener('popstate', (event) => {
  console.log('Navigation state:', event.state)
  console.log('History length:', history.length)
})

// Access current state
console.log('Current state:', history.state)
console.log('History entries:', history.length)

Location API

Location

import { Location, TaroLocation } from '@tarojs/runtime'

interface TaroLocation {
  // URL components
  protocol: string     // "https:"
  host: string        // "example.com:8080"  
  hostname: string    // "example.com"
  port: string        // "8080"
  pathname: string    // "/path/to/page"
  search: string      // "?param=value"
  hash: string        // "#section"
  href: string        // Full URL
  origin: string      // "https://example.com:8080"
  
  // Navigation methods
  assign(url: string): void
  replace(url: string): void  
  reload(): void
  toString(): string
}

// Global location instance
const location: TaroLocation

Key Features

  • URL Parsing: Automatically parses and validates URLs
  • History Integration: Navigation methods update history appropriately
  • Hash Navigation: Supports hash-based routing with hashchange events
  • Cross-platform: Works consistently across web and mini-program platforms

Usage Examples

// Read URL components
console.log('Current page:', location.pathname)
console.log('Query params:', location.search)
console.log('Hash fragment:', location.hash)
console.log('Full URL:', location.href)

// Navigation
location.assign('/new-page')        // Navigate to new page (adds history entry)
location.replace('/replacement')    // Replace current page (no history entry)
location.reload()                   // Reload current page

// URL manipulation
location.hash = '#new-section'      // Update hash
location.search = '?param=value'    // Update query params

// Listen for hash changes
window.addEventListener('hashchange', () => {
  console.log('Hash changed to:', location.hash)
})

Navigator API

navigator

import { navigator } from '@tarojs/runtime'

interface Navigator {
  readonly appCodeName: string      // "Mozilla"
  readonly appName: string         // "Netscape"  
  readonly appVersion: string      // Version string
  readonly cookieEnabled: boolean  // true
  readonly onLine: boolean        // true
  readonly platform: string       // "MacIntel" 
  readonly product: string        // "Gecko"
  readonly productSub: string     // "20030107"
  readonly userAgent: string      // User agent string
  readonly vendor: string         // "Google Inc."
  readonly vendorSub: string      // ""
}

Usage Examples

// Detect platform/browser
console.log('Platform:', navigator.platform)
console.log('User Agent:', navigator.userAgent)
console.log('Online status:', navigator.onLine)

// Feature detection
if (navigator.cookieEnabled) {
  // Cookies are supported
}

// App information
console.log('App name:', navigator.appName)
console.log('App version:', navigator.appVersion)

URL APIs

URL

import { URL, TaroURL } from '@tarojs/runtime'

interface TaroURL {
  // URL components  
  protocol: string
  hostname: string
  host: string
  port: string
  pathname: string  
  search: string
  hash: string
  href: string
  origin: string
  
  // Search parameters
  searchParams: URLSearchParams
  
  // Methods
  toString(): string
  toJSON(): string
  
  // Static methods (throw in mini-programs)
  static createObjectURL(object: any): string
  static revokeObjectURL(url: string): void
}

// Constructor
new URL(url: string, base?: string | URL): TaroURL

Usage Examples

// Parse URL
const url = new URL('https://example.com:8080/path?param=value#section')

console.log('Protocol:', url.protocol)    // "https:"
console.log('Host:', url.host)           // "example.com:8080"
console.log('Pathname:', url.pathname)   // "/path"
console.log('Search:', url.search)       // "?param=value"
console.log('Hash:', url.hash)          // "#section"

// Manipulate URL
url.pathname = '/new-path'
url.searchParams.set('newParam', 'newValue')
url.hash = '#new-section'

console.log('Updated URL:', url.toString())

// Relative URLs
const relative = new URL('/relative', 'https://example.com')
console.log('Absolute URL:', relative.href)

URLSearchParams

import { URLSearchParams } from '@tarojs/runtime'

interface URLSearchParams {
  // Manipulation methods
  append(name: string, value: string): void
  delete(name: string): void  
  get(name: string): string | null
  getAll(name: string): string[]
  has(name: string): boolean
  set(name: string, value: string): void
  
  // Iteration
  keys(): IterableIterator<string>
  values(): IterableIterator<string>
  entries(): IterableIterator<[string, string]>
  forEach(callback: (value: string, key: string, parent: URLSearchParams) => void): void
  
  // Serialization
  toString(): string
}

// Constructor
new URLSearchParams(init?: string | URLSearchParams | Record<string, string>): URLSearchParams

Usage Examples

// Create from string
const params = new URLSearchParams('?name=John&age=30&hobby=reading&hobby=gaming')

// Basic operations
console.log('Name:', params.get('name'))           // "John"
console.log('All hobbies:', params.getAll('hobby')) // ["reading", "gaming"]
console.log('Has email:', params.has('email'))      // false

// Modify parameters
params.set('age', '31')              // Update existing
params.append('hobby', 'cooking')    // Add new value
params.delete('name')                // Remove parameter

// Iterate over parameters
params.forEach((value, key) => {
  console.log(`${key}: ${value}`)
})

for (const [key, value] of params.entries()) {
  console.log(`${key} = ${value}`)
}

// Convert to string
console.log('Query string:', params.toString()) // "age=31&hobby=reading&hobby=gaming&hobby=cooking"

Animation APIs

requestAnimationFrame / cancelAnimationFrame

import { requestAnimationFrame, cancelAnimationFrame, now } from '@tarojs/runtime'

// Animation frame scheduling
function requestAnimationFrame(callback: FrameRequestCallback): number
function cancelAnimationFrame(handle: number): void

// High-resolution timestamp
function now(): number

type FrameRequestCallback = (timestamp: number) => void

Key Features

  • Cross-platform: Uses native requestAnimationFrame on web, setTimeout fallback on mini-programs
  • Performance Timing: Provides high-resolution timestamps via now()
  • Throttling: Automatically throttles to ~60fps (16ms intervals) on platforms without native support

Usage Examples

// Basic animation
function animate(timestamp: number) {
  // Animation logic here
  console.log('Frame at:', timestamp)
  
  // Continue animation
  requestAnimationFrame(animate)
}

// Start animation
const animationId = requestAnimationFrame(animate)

// Cancel animation
cancelAnimationFrame(animationId)

// Performance timing
const start = now()
// ... some work
const duration = now() - start
console.log('Operation took:', duration, 'ms')

// Smooth animation with timing
let startTime: number | null = null

function step(timestamp: number) {
  if (!startTime) startTime = timestamp
  
  const progress = (timestamp - startTime) / 1000 // 1 second animation
  
  if (progress < 1) {
    // Update animation state based on progress
    updateAnimation(progress)
    requestAnimationFrame(step)
  } else {
    // Animation complete
    finishAnimation()
  }
}

requestAnimationFrame(step)

GetComputedStyle

getComputedStyle

import { getComputedStyle } from '@tarojs/runtime'

function getComputedStyle(
  element: Element, 
  pseudoElement?: string | null
): CSSStyleDeclaration

interface CSSStyleDeclaration {
  [property: string]: string
  cssText: string
  length: number
  
  // Property access methods
  getPropertyValue(property: string): string
  setProperty(property: string, value: string, priority?: string): void
  removeProperty(property: string): string
}

Usage Examples

// Get computed styles
const element = document.getElementById('my-element')
const styles = getComputedStyle(element)

// Access individual properties  
console.log('Color:', styles.color)
console.log('Font size:', styles.fontSize)
console.log('Display:', styles.display)

// Access via getPropertyValue
console.log('Background:', styles.getPropertyValue('background-color'))

// Get all CSS text
console.log('All styles:', styles.cssText)

// Pseudo-element styles (web only)
const beforeStyles = getComputedStyle(element, '::before')
console.log('Before content:', beforeStyles.content)

Platform Considerations

Mini-Program Limitations

Some browser APIs have limitations on mini-program platforms:

// These throw errors on mini-programs
try {
  URL.createObjectURL(blob)  // Not supported
  URL.revokeObjectURL(url)   // Not supported  
} catch (error) {
  console.log('Not available on mini-programs')
}

// Fallback implementations
const styles = getComputedStyle(element) // Falls back to element.style
const timestamp = now() // Uses Date.now() if performance API unavailable

Context Switching

The window object manages page contexts automatically:

// Context actions (internal use)
window.CONTEXT_ACTIONS.INIT     // Initialize new page  
window.CONTEXT_ACTIONS.RESTORE  // Restore cached page
window.CONTEXT_ACTIONS.RECOVER  // Recover from cache
window.CONTEXT_ACTIONS.DESTORY  // Clean up page context

The BOM APIs provide a complete browser environment that enables seamless cross-platform development while maintaining optimal performance on each target platform.

Install with Tessl CLI

npx tessl i tessl/npm-tarojs--runtime

docs

bom.md

dom.md

framework-integration.md

index.md

types.md

utilities.md

tile.json