sheep2.js is the second version of the little sheep watermark in the bottom right corner of the page. Try right-clicking or long pressing it! It's the successor of sheep.js, and was used for almost all web pages created between 2017-11-30 and 2018-12-14, when sheep3.js was created.
In sheep2.js, the little sheep has a new name: l' ŝafeto. It is a terse form of "la eta ŝafo," Esperanto for "the little sheep."
Generally, sheep2.js has roughly the same features as sheep.js, as most of the improvements were on the code quality side.
Clicking on l' ŝafeto brings you to the home page.
L' ŝafeto is focusable but otherwise remains inaccessible (pressing enter/space does not click it).
L' ŝafeto can be dragged (with touch support), and its new location is persistent until manually reset.
Support for a notification system, carried over from sheep.js. Multiple notifications stack bottom up. Unlike sheep.js, sheep2.js does not create any notifications on page load.
Right clicking twice on l' ŝafeto opens the default browser context menu. However, for some reason sheep2.js's implementation is jankier than sheep.js, and sometimes quickly closing the context menu and right clicking again brings up the native browser menu, which is not intended.
Right-clicking or long-pressing on l' ŝafeto opens a context menu with various options. While now it looks uglier than sheep.js's context menu, I believe I designed it based on Chrome's context menu at the time, with sharp corners and a border. I was a big fan of Chrome's context menu for some reason.
go to index page — Sends the user to the home page; same as just clicking on l' ŝafeto.
hide l' ŝafeto — Hides l' ŝafeto for the rest of the session.
reset l' ŝafeto position — Resets the persistent custom l' ŝafeto location back to the bottom right corner.
see page description — Displays the page description in a notification. The description is the same as what displays on Discord in the website embed when you paste a link to the page.
eval.js — Launches the eval.js bookmarklet, which opens a basic JavaScript REPL for mobile and school Chromebook users to run JavaScript on the page.
view source code — This was added fairly recently in 2023. It sends the user to the corresponding HTML file page on GitHub.
site search — This was added fairly recently in 2024. Opens the same sitewide search dialog as on the home page.
sheep2.css contains a CSS reset:
Changes the text selection highlight color to a nice aqua.
Makes form elements inherit the page font.
Buttons get the pointer cursor on hover.
Defines the fadein and fadeout animations, which do as their names imply.
fadein
fadeout
L' ŝafeto is a custom <sheep-btn> element, and it can be hidden by adding the no-sheep class to <body>.
<sheep-btn>
no-sheep
<body>
SHEEP
One of the reasons I wrote sheep2.js was to relax the requirement that the script be loaded in the document body, and to avoid injecting the stylesheet dynamically, which I felt was bad practice (since it slightly increases load times).
<link rel="stylesheet" type="text/css" href="../sheep2.css"> <script src="../sheep2.js" charset="utf-8"></script>
window.cookie — An alias for the localStorage API, but wrapped in a try-catch so in some browsers' private modes, accessing window.cookie won't throw if localStorage is disabled.
window.cookie
localStorage
try
catch
SHEEP.version: 2
SHEEP.getPref(name: string, defaultValue?: any): any — Preferences are stored as a JSON object under the localStorage key preferences.
SHEEP.getPref(name: string, defaultValue?: any): any
preferences
SHEEP.setPref<T>(name: string, value: T): T — Immediately saves the preference to localStorage.
SHEEP.setPref<T>(name: string, value: T): T
SHEEP.ajax(url: string, callback: (response: string) => void, error?: (response: string, statusCode: number) => void): void — A utility function inspired by jQuery's $.ajax. Non-200 status codes are considered errors.
SHEEP.ajax(url: string, callback: (response: string) => void, error?: (response: string, statusCode: number) => void): void
$.ajax
SHEEP.getAjaxCode(): string — Returns the source code of SHEEP.ajax. I believe I added this so I could quickly copy and paste the boilerplate for XMLHttpRequest.
SHEEP.getAjaxCode(): string
SHEEP.ajax
XMLHttpRequest
SHEEP.menuItems: string[]SHEEP.menuActions: (() => void)[] — A pair of lists that acts as the menu item registry for sheep2.js. SHEEP.menuItems contains menu item labels, and SHEEP.menuActions contains menu item handlers.
SHEEP.menuItems: string[]SHEEP.menuActions: (() => void)[]
SHEEP.menuItems
SHEEP.menuActions
SHEEP.registerMenuItem(label: string, action: () => void, insertIndex?: number): void — Inserts a menu item at the given index. Due to a bug in how I implemented it, it is not possible to insert an item at the beginning of the menu.
SHEEP.registerMenuItem(label: string, action: () => void, insertIndex?: number): void
SHEEP.escapeHTML(str: string): string — Escapes &, <, and >, but not ", so this should not be used for adding text to attributes.
SHEEP.escapeHTML(str: string): string
&
<
>
"
SHEEP.textWidth(text: string, fontStyle: string | Element, getHeightToo?: boolean): { width: number, height?: number } — Measures the rendered width of text with the given font, either as a CSS font or extracted from the element's styles.
SHEEP.textWidth(text: string, fontStyle: string | Element, getHeightToo?: boolean): { width: number, height?: number }
font
SHEEP.notify(content: string, onclick?: () => void, dismissTime?: number): void — Creates a notification. content contains HTML. onclick is fired when the user explicitly clicks on the notification to close it. dismissTime is a nonzero number of milliseconds after which the notification will auto-dismiss. If both onclick and dismissTime are omitted, "Click to close" is added to the notification.
SHEEP.notify(content: string, onclick?: () => void, dismissTime?: number): void
content
onclick
dismissTime