SkillAgentSearch skills...

Primrose

A syntax-highlighting text editors that renders to an HTML5 Canvas

Install / Use

/learn @capnmidnight/Primrose

README

PRIMROSE TEXT EDITOR

Primrose is a syntax highlighting text editor that renders into an HTML5 Canvas element. This is particularly useful for texturing 3D objects in WebGL apps.

Features

  • International keyboard support (left-to-right rendering only)
  • Wide Unicode character-aware
  • Line numbering
  • Color theming
  • Syntax highlighting for:
    • JavaScript,
    • HTML, and
    • BASIC
<hr>

Liscense

Primrose is free, open source software (MIT) and may readily be used with other FOSS projects.

<hr>

Contributing

Conduct

First, please read the Conduct Policy.

Contributions

If you think you can be a polite person in accordance with the Conduct Policy, I'd be more than happy to add anyone who asks as a contributor. Just email me your profile info and a brief description of what you'd like to work on.

<hr>

Getting started with Primrose

In a 2D page

Here is a basic example that creates an editor in a 2D web page.

index.html

<html>
   <body>
      <primrose style="width:50em;height:25em"></primrose>
   </body>
   <script type="module" src="node_modules/primrose/src/primrose.js"></script>
</html>

In a 3D WebGL app

Here is a basic example that creates an editor in a 3D WebGL app, using Three.js.

<em>NOTE: While Primrose can manage most input events on its own, in WebGL contexts, it's not able to figure out what the user's pointer is pointing at. Mouse or VR motion controller support requires implementing Raycast-based picking on your own. However, Primrose does offer a simple interface for implementing pointer operations.</em>

<hr>

API

The documentation here represents the public API. Any properties, methods, functions, or classes not listed here are considered either internal state or deprecated features and may change or be removed at any time.

<hr>

Primrose

The Primrose class extends the EventTarget class. It is a text editor control that renders to an HTML5 Canvas, using the CanvasRenderingContext2D API.

Importing

To get the Primrose class, import it from the package bundle:

import { Primrose } from "./node_modules/primrose/primrose.js";

There is also a minified version:

import { Primrose } from "./node_modules/primrose/primrose.min.js";

You can also import without package bundling, which is probably preferred if you intend to build your own bundle:

import { Primrose } from "./node_modules/primrose/src/primrose.js";
<hr>

Constructor

You create a Primrose control in one of two ways. In creating the control, there are a set of options that you can specify. The two ways are:

In HTML

Create a <primrose> tag in your document before the page has loaded.

Specify the options as a comma seperated list of key-value pairs, each separated by an equals sign (=), on an attribute on the tag named data-options.

Example
<primrose data-options="lineNumbers=false;wordWrap=false"></primrose>
In JavaScript

Create a new instance of the Primrose class, passing the options as a JavaScript object

Example
new Primrose({ lineNumbers: false, wordWrap: false });
Options

The options object has the following fields:

  • element:(HTMLElement|HTMLCanvasElement|OffscreenCanvas) - Default: null - a document element or a canvas that represents the Primrose control. This can either be:
    • a <primrose> tag (which is a generic HTML tag in DOM), in which case the editor Canvas will be inserted into the <primrose> tag, or
    • an HTMLCanvasElement element or OffscreeCanvas object, in which case the editor will take control of the canvas.
    • null, which instructs Primrose to construct its own Canvas element. If OffscreenCanvas is available, that will be used instead of HTMLCanvasElement.
  • width:Number - Default: undefined - the scale-independent width of the canvas used when element is null
  • height:Number - Default: undefined - the scale-independent height of the canvas used when element is null
  • padding:Number - Default: 0 - the scale-independent amount of inset for rendering the contents from the edge of the canvas. This is useful for texturing objects where the texture edge cannot be precisely controlled.
  • fontSize:Number - Default: 16 - the scale-independent height to draw characters.
  • scaleFactor:Number - *Default: window.devicePixelRatio - A multiplicative factor for how large to scale the width, height, fontSize, and padding of the canvas, to improve rendering sharpness on high-resolution displays. With THREE.js, it's best to set this value to 1 and change the width, height, and fontSize manually.
  • readOnly:Boolean - Default: false - indicates whether or not the text editor should allow changes to its value.
  • multiLine:Boolean - Default: true - indicates whether or not the text editor should break long lines onto new lines.
  • scrollBars:Boolean - Default: true - indicates whether or not scroll bars should be rendered at the right and bottom in the control. If wordWrap is enabled, the bottom, horizontal scrollbar will not be rendered.
  • lineNumbers:Boolean - Default: true - indicates whether or not line numbers should be rendered on the left side of the control.
  • language:String - Default: "JavaScript" - A name for the type of syntax highlighting to perform. This value is not case-sensitive. Valid values are:
    • "basic" for Basic,
    • "bas" for Basic,
    • "html" for HTML,
    • "javascript" for JavaScript,
    • "js" for JavaScript,
    • "plaintext" for PlainText,
    • "txt" for PlainText
    • and any case-variation thereof.
<hr>

Events

The events in Primrose are all of type Event, having no other properties set on them. The only way to register the events is to call addEventListener, i.e. there are no on### properties on the object for the event handlers.

  • change:Event - Fires when the text in the control has changed.
  • blur:Event - Fires when the control first loses focus. Calls to blur() while the control is not focused will not fire the blur event.
  • focus:Event - Fires when the control first gains focus. Calls to focus() while the control is focused will not fire the focus event.
  • over:Event - Fires when the control is first hovered over by a pointer.
  • out:Event - Fires the first time the controller is no longer hovered over by a pointer.
  • update:Event - Fires when the Primrose control finishes rendering.
<hr>

Public Methods

<hr>
addEventListener(type:String, handler:Function(evt:Event))

Add a listener for one of the event types listed above.

Example
const editor = new Primrose({
    element: document.querySelector("canvas")
});

function onChange(){
    console.log("changed!");
}

editor.addEventListener("change", onChange);
editor.value = "Something"; // 'changed!' printed out to console.
Parameters
  • name:String - The name of the event to register, one of the event names listed in the Events section above.
  • handler:Function(evt:Event) - A callback function to receive the event. This function will be provided an argument of type Event
<hr>
removeEventListener(type:String, handler:Function(evt:[Event](https://developer.mozilla.o
View on GitHub
GitHub Stars532
CategoryDevelopment
Updated1mo ago
Forks66

Languages

JavaScript

Security Score

85/100

Audited on Jan 28, 2026

No findings