or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

document-management.mdevent-system.mdindex.mdposition-tracking.mdshared-data-types.mdsnapshot-system.mdsynchronization.mdtransaction-system.mdundo-redo-system.mdxml-types.md

xml-types.mddocs/

0

# XML Types

1

2

XML-aware collaborative types for structured document editing with DOM integration. These types enable collaborative editing of XML/HTML documents while maintaining proper document structure and supporting real-time synchronization.

3

4

## Capabilities

5

6

### YXmlFragment

7

8

Container type for XML elements and text nodes, providing the foundation for structured document editing.

9

10

```typescript { .api }

11

/**

12

* XML container that can hold XML elements and text nodes

13

*/

14

class YXmlFragment {

15

constructor();

16

17

/** Number of child elements in the fragment */

18

readonly length: number;

19

20

/** First child element or null if empty */

21

readonly firstChild: YXmlElement | YXmlText | null;

22

}

23

```

24

25

**Fragment Modification Methods:**

26

27

```typescript { .api }

28

/**

29

* Insert child nodes at the specified index

30

* @param index - Position to insert at

31

* @param content - Array of XML elements or text nodes to insert

32

*/

33

insert(index: number, content: Array<YXmlElement | YXmlText>): void;

34

35

/**

36

* Insert child nodes after a reference node

37

* @param ref - Reference node to insert after (null for beginning)

38

* @param content - Array of XML elements or text nodes to insert

39

*/

40

insertAfter(ref: null | Item | YXmlElement | YXmlText, content: Array<YXmlElement | YXmlText>): void;

41

42

/**

43

* Delete child nodes starting at index

44

* @param index - Starting position for deletion

45

* @param length - Number of children to delete (default: 1)

46

*/

47

delete(index: number, length?: number): void;

48

49

/**

50

* Append child nodes to the end

51

* @param content - Array of XML elements or text nodes to append

52

*/

53

push(content: Array<YXmlElement | YXmlText>): void;

54

55

/**

56

* Prepend child nodes to the beginning

57

* @param content - Array of XML elements or text nodes to prepend

58

*/

59

unshift(content: Array<YXmlElement | YXmlText>): void;

60

```

61

62

**Fragment Access Methods:**

63

64

```typescript { .api }

65

/**

66

* Get child node at the specified index

67

* @param index - Index of child to retrieve

68

* @returns Child node or undefined

69

*/

70

get(index: number): YXmlElement | YXmlText;

71

72

/**

73

* Get slice of children as JavaScript Array

74

* @param start - Start index (default: 0)

75

* @param end - End index (default: length)

76

* @returns Array of child nodes

77

*/

78

slice(start?: number, end?: number): Array<YXmlElement | YXmlText>;

79

80

/**

81

* Convert all children to JavaScript Array

82

* @returns Array of all child nodes

83

*/

84

toArray(): Array<YXmlElement | YXmlText | YXmlHook>;

85

```

86

87

**Fragment Iteration and Selection:**

88

89

```typescript { .api }

90

/**

91

* Execute function for each child node

92

* @param f - Function to execute for each child

93

*/

94

forEach(f: (item: YXmlElement | YXmlText, index: number, fragment: YXmlFragment) => void): void;

95

96

/**

97

* Create a tree walker for traversing the fragment

98

* @param filter - Optional filter function for nodes

99

* @returns Tree walker instance

100

*/

101

createTreeWalker(filter?: (node: AbstractType<any>) => boolean): YXmlTreeWalker;

102

103

/**

104

* Find the first element matching a CSS selector

105

* @param query - CSS selector string

106

* @returns First matching element or null

107

*/

108

querySelector(query: string): YXmlElement | YXmlText | YXmlHook | null;

109

110

/**

111

* Find all elements matching a CSS selector

112

* @param query - CSS selector string

113

* @returns Array of matching elements

114

*/

115

querySelectorAll(query: string): Array<YXmlElement | YXmlText | YXmlHook | null>;

116

```

117

118

**Fragment Serialization:**

119

120

```typescript { .api }

121

/**

122

* Convert fragment to XML string

123

* @returns XML string representation

124

*/

125

toString(): string;

126

127

/**

128

* Convert to JSON representation

129

* @returns JSON string

130

*/

131

toJSON(): string;

132

133

/**

134

* Convert to DOM DocumentFragment

135

* @param document - Document to create nodes in (default: globalThis.document)

136

* @param hooks - Custom hooks for special elements

137

* @param binding - Optional binding object

138

* @returns DOM DocumentFragment

139

*/

140

toDOM(document?: Document, hooks?: { [key: string]: any }, binding?: any): DocumentFragment;

141

142

/**

143

* Create a copy of the fragment

144

* @returns New YXmlFragment with same content

145

*/

146

clone(): YXmlFragment;

147

```

148

149

**Usage Examples:**

150

151

```typescript

152

import * as Y from "yjs";

153

154

const doc = new Y.Doc();

155

const xmlFragment = doc.getXmlFragment("document");

156

157

// Create XML elements

158

const header = new Y.XmlElement("h1");

159

const paragraph = new Y.XmlElement("p");

160

const textNode = new Y.XmlText();

161

162

textNode.insert(0, "Hello World!");

163

header.insert(0, [textNode]);

164

165

// Insert into fragment

166

xmlFragment.push([header, paragraph]);

167

168

// Query elements

169

const h1 = xmlFragment.querySelector("h1");

170

const allPs = xmlFragment.querySelectorAll("p");

171

172

// Convert to DOM

173

const domFragment = xmlFragment.toDOM();

174

document.body.appendChild(domFragment);

175

```

176

177

### YXmlElement

178

179

XML element with attributes that can contain child elements and text nodes.

180

181

```typescript { .api }

182

/**

183

* XML element with attributes and children

184

*/

185

class YXmlElement<KV = { [key: string]: any }> extends YXmlFragment {

186

constructor(nodeName?: string);

187

188

/** Tag name of the XML element */

189

readonly nodeName: string;

190

191

/** Next sibling element or null */

192

readonly nextSibling: YXmlElement | YXmlText | null;

193

194

/** Previous sibling element or null */

195

readonly prevSibling: YXmlElement | YXmlText | null;

196

}

197

```

198

199

**Element Attribute Methods:**

200

201

```typescript { .api }

202

/**

203

* Set an attribute on the element

204

* @param attributeName - Name of the attribute

205

* @param attributeValue - Value to set

206

*/

207

setAttribute<KEY extends keyof KV>(attributeName: KEY, attributeValue: KV[KEY]): void;

208

209

/**

210

* Get an attribute from the element

211

* @param attributeName - Name of the attribute

212

* @returns Attribute value or undefined

213

*/

214

getAttribute<KEY extends keyof KV>(attributeName: KEY): KV[KEY] | undefined;

215

216

/**

217

* Check if element has an attribute

218

* @param attributeName - Name of the attribute to check

219

* @returns True if attribute exists

220

*/

221

hasAttribute(attributeName: string): boolean;

222

223

/**

224

* Remove an attribute from the element

225

* @param attributeName - Name of the attribute to remove

226

*/

227

removeAttribute(attributeName: string): void;

228

229

/**

230

* Get all attributes from the element

231

* @param snapshot - Optional snapshot for historical state

232

* @returns Object with all attributes

233

*/

234

getAttributes(snapshot?: Snapshot): { [key: string]: any };

235

```

236

237

**Element Serialization:**

238

239

```typescript { .api }

240

/**

241

* Convert element to XML string with attributes

242

* @returns XML string representation

243

*/

244

toString(): string;

245

246

/**

247

* Convert to DOM Element

248

* @param document - Document to create element in (default: globalThis.document)

249

* @param hooks - Custom hooks for special elements

250

* @param binding - Optional binding object

251

* @returns DOM Element

252

*/

253

toDOM(document?: Document, hooks?: { [key: string]: any }, binding?: any): Element;

254

255

/**

256

* Create a copy of the element

257

* @returns New YXmlElement with same content and attributes

258

*/

259

clone(): YXmlElement<KV>;

260

```

261

262

**Usage Examples:**

263

264

```typescript

265

import * as Y from "yjs";

266

267

const doc = new Y.Doc();

268

const xmlFragment = doc.getXmlFragment("document");

269

270

// Create an element with attributes

271

const div = new Y.XmlElement("div");

272

div.setAttribute("class", "container");

273

div.setAttribute("id", "main-content");

274

275

// Add text content

276

const text = new Y.XmlText();

277

text.insert(0, "Hello World!");

278

div.insert(0, [text]);

279

280

// Create nested structure

281

const article = new Y.XmlElement("article");

282

const title = new Y.XmlElement("h2");

283

const titleText = new Y.XmlText();

284

titleText.insert(0, "Article Title");

285

title.insert(0, [titleText]);

286

287

article.push([title, div]);

288

xmlFragment.push([article]);

289

290

// Work with attributes

291

console.log(div.getAttribute("class")); // "container"

292

div.removeAttribute("id");

293

294

// Convert to DOM

295

const domElement = article.toDOM();

296

```

297

298

### YXmlText

299

300

XML text node with formatting support for rich text within XML structures.

301

302

```typescript { .api }

303

/**

304

* XML text node with rich formatting capabilities

305

*/

306

class YXmlText extends YText {

307

constructor();

308

309

/** Next sibling element or null */

310

readonly nextSibling: YXmlElement | YXmlText | null;

311

312

/** Previous sibling element or null */

313

readonly prevSibling: YXmlElement | YXmlText | null;

314

}

315

```

316

317

**XML Text Methods:**

318

319

```typescript { .api }

320

/**

321

* Convert to formatted XML string

322

* @returns XML string with formatting

323

*/

324

toString(): string;

325

326

/**

327

* Convert to JSON representation

328

* @returns JSON string

329

*/

330

toJSON(): string;

331

332

/**

333

* Convert to DOM Text node

334

* @param document - Document to create text node in (default: globalThis.document)

335

* @param hooks - Custom hooks for special formatting

336

* @param binding - Optional binding object

337

* @returns DOM Text node

338

*/

339

toDOM(document?: Document, hooks?: { [key: string]: any }, binding?: any): Text;

340

341

/**

342

* Create a copy of the text node

343

* @returns New YXmlText with same content

344

*/

345

clone(): YXmlText;

346

```

347

348

**Usage Examples:**

349

350

```typescript

351

import * as Y from "yjs";

352

353

const doc = new Y.Doc();

354

const xmlFragment = doc.getXmlFragment("document");

355

356

// Create formatted text

357

const xmlText = new Y.XmlText();

358

xmlText.insert(0, "Hello ");

359

xmlText.insert(6, "World", { bold: true });

360

xmlText.insert(11, "!");

361

362

// Add to element

363

const paragraph = new Y.XmlElement("p");

364

paragraph.insert(0, [xmlText]);

365

xmlFragment.push([paragraph]);

366

367

// Convert to DOM

368

const domText = xmlText.toDOM();

369

```

370

371

### YXmlHook

372

373

Custom XML element hook for extending XML functionality with custom components.

374

375

```typescript { .api }

376

/**

377

* Custom XML hook for extending functionality

378

*/

379

class YXmlHook extends YMap {

380

constructor(hookName: string);

381

382

/** Name of the hook */

383

readonly hookName: string;

384

}

385

```

386

387

**Hook Methods:**

388

389

```typescript { .api }

390

/**

391

* Convert hook to DOM element using custom rendering

392

* @param document - Document to create element in (default: globalThis.document)

393

* @param hooks - Hook implementation functions

394

* @param binding - Optional binding object

395

* @returns DOM Element

396

*/

397

toDOM(document?: Document, hooks?: { [key: string]: any }, binding?: any): Element;

398

399

/**

400

* Create a copy of the hook

401

* @returns New YXmlHook with same hook name and data

402

*/

403

clone(): YXmlHook;

404

```

405

406

**Usage Examples:**

407

408

```typescript

409

import * as Y from "yjs";

410

411

const doc = new Y.Doc();

412

const xmlFragment = doc.getXmlFragment("document");

413

414

// Create a custom hook

415

const customComponent = new Y.XmlHook("custom-widget");

416

customComponent.set("type", "chart");

417

customComponent.set("data", [1, 2, 3, 4, 5]);

418

419

xmlFragment.push([customComponent]);

420

421

// Convert to DOM with custom hook handler

422

const domFragment = xmlFragment.toDOM(document, {

423

"custom-widget": (hook) => {

424

const element = document.createElement("div");

425

element.className = "custom-widget";

426

element.textContent = `Chart with ${hook.get("data").length} points`;

427

return element;

428

}

429

});

430

```

431

432

### YXmlTreeWalker

433

434

Iterator for traversing XML tree structures with optional filtering.

435

436

```typescript { .api }

437

/**

438

* Tree walker for traversing XML structures

439

*/

440

class YXmlTreeWalker {

441

constructor(root: YXmlFragment | YXmlElement, filter?: (node: AbstractType<any>) => boolean);

442

443

/**

444

* Get next node in traversal

445

* @returns Iterator result with next node

446

*/

447

next(): IteratorResult<YXmlElement | YXmlText | YXmlHook>;

448

449

/**

450

* Iterator support for for...of loops

451

*/

452

[Symbol.iterator](): YXmlTreeWalker;

453

}

454

```

455

456

**Usage Examples:**

457

458

```typescript

459

import * as Y from "yjs";

460

461

const doc = new Y.Doc();

462

const xmlFragment = doc.getXmlFragment("document");

463

464

// Create tree structure

465

const root = new Y.XmlElement("div");

466

const child1 = new Y.XmlElement("p");

467

const child2 = new Y.XmlElement("span");

468

root.push([child1, child2]);

469

xmlFragment.push([root]);

470

471

// Walk the tree

472

const walker = xmlFragment.createTreeWalker();

473

for (const node of walker) {

474

if (node instanceof Y.XmlElement) {

475

console.log(`Element: ${node.nodeName}`);

476

} else if (node instanceof Y.XmlText) {

477

console.log(`Text: ${node.toString()}`);

478

}

479

}

480

481

// Walk with filter

482

const elementWalker = xmlFragment.createTreeWalker(

483

node => node instanceof Y.XmlElement

484

);

485

for (const element of elementWalker) {

486

console.log(`Element: ${element.nodeName}`);

487

}

488

```