Jump to content

Docs: Difference between revisions

Poopman (talk | contribs)
m added more vars
Dat Hack3r (talk | contribs)
m Added page to Documentation category.
 
(43 intermediate revisions by 4 users not shown)
Line 1: Line 1:
=Our World Of Text=
=Our World Of Text=
This page contains documentation of the OWOT codebase, examples, and code locations.


If you want to talk about this page, go to [[Talk:Docs]]
===Code Documentation===
===Code Documentation===


==OWOT.js==
==OWOT.js==
=== Event Listeners: ===
{| class="wikitable"
|+
!Object
!Listen Event
!Functions/Events Fired
!Emits
!Example Usage
!Related Code
|-
|window
|load
|
|"clientLoaded"
|
|<syntaxhighlight lang="javascript" line="1" start="187">
window.addEventListener("load", function() {
w.emit("clientLoaded");
});
</syntaxhighlight>
|-
|
|hash change
|manageCoordHash();
|
|https://ourworldoftext.com/#x:10,y:20
|<syntaxhighlight lang="javascript" line="1" start="5639">
window.onhashchange = function(e) {
manageCoordHash();
}
</syntaxhighlight>
|-
|
|before unload
|if(writeBuffer.length) flushWrites();
|
|
|<syntaxhighlight lang="javascript" line="1" start="5643">
window.onbeforeunload = function() {
if(writeBuffer.length) flushWrites();
}
</syntaxhighlight>
|-
|
|resize
|event_resize
|("resize", ratio)
|
|<syntaxhighlight lang="javascript" line="1" start="1192">
window.addEventListener("resize", event_resize);
</syntaxhighlight>
|-
|document
|select start
|self
|
|
|<syntaxhighlight lang="javascript" line="1" start="5647">
document.onselectstart = function(e) {
var target = e.target;
if(closest(target, getChatfield()) || target == elm.chatbar || closest(target, elm.confirm_js_code) || closest(target, elm.announce_text)) {
return true;
}
return Modal.isOpen;
}
</syntaxhighlight>
|-
|
|key down
|
* keydown_regionSelect
* event_keydown_copy_char
* event_keydown_copy_color
* event_keydown
|
|
|<syntaxhighlight lang="javascript" line="1" start="525">
document.addEventListener("keydown", keydown_regionSelect);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="1344">
document.addEventListener("keydown", event_keydown_copy_char);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="1371">
document.addEventListener("keydown", event_keydown_copy_color);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="2955">
document.addEventListener("keydown", event_keydown);
</syntaxhighlight>
|-
|
|key up
|event_keyup
|("keyUp", e);
|
|<syntaxhighlight lang="javascript" line="1" start="2957">
function event_keyup(e) {
w.emit("keyUp", e);
}
</syntaxhighlight>
|-
|
|mouse move
|
* mousemove_tileProtectAuto
* mousemove_linkAuto
* event_mousemove
|("mouseMove", {
tileX: tileX,
tileY: tileY,
charX: charX,
charY: charY,
pageX: pageX,
pageY: pageY
})
|
|<syntaxhighlight lang="javascript" line="1" start="945">
document.addEventListener("mousemove", mousemove_tileProtectAuto);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="1075">
document.addEventListener("mousemove", mousemove_linkAuto);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="3321">
document.addEventListener("mousemove", event_mousemove);
</syntaxhighlight>
|-
|
|mouse down
|event_mousedown
|("mouseDown", {
tileX: pos[0],
tileY: pos[1],
charX: pos[2],
charY: pos[3],
pageX: pageX,
pageY: pageY
});
|
|<syntaxhighlight lang="javascript" line="1" start="1771">
document.addEventListener("mousedown", event_mousedown);
</syntaxhighlight>
|-
|
|mouse up
|event_mouseup
|
|
|<syntaxhighlight lang="javascript" line="1" start="1947">
document.addEventListener("mouseup", event_mouseup);
</syntaxhighlight>
|-
|
|mouse enter
|event_mouseenter
|("mouseEnter", e)
|
|<syntaxhighlight lang="javascript" line="1" start="1958">
document.addEventListener("mouseenter", event_mouseenter);
</syntaxhighlight>
|-
|
|touch start
|event_touchstart
|
|
|<syntaxhighlight lang="javascript" line="1" start="3452">
document.addEventListener("touchstart", event_touchstart);
</syntaxhighlight>
|-
|
|touch end
|event_touchend
|
|
|<syntaxhighlight lang="javascript" line="1" start="3453">
document.addEventListener("touchend", event_touchend);
</syntaxhighlight>
|-
|
|touch move
|event_touchmove
|
|
|<syntaxhighlight lang="javascript" line="1" start="3454">
document.addEventListener("touchmove", event_touchmove, { passive: false });
</syntaxhighlight>
|-
|
|wheel
|
* event_wheel
* event_wheel_zoom
|("scroll", {
deltaX: -deltaX,
deltaY: -deltaY
});
|
|<syntaxhighlight lang="javascript" line="1" start="3487">
document.addEventListener("wheel", event_wheel);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="3537">
document.addEventListener("wheel", event_wheel_zoom, {
passive: false
});
</syntaxhighlight>
|-
|document.body
|key down
|
* keydown_tileProtectAuto
* keydown_linkAuto
|
|
|<syntaxhighlight lang="javascript" line="1" start="1012">
document.body.addEventListener("keydown", keydown_tileProtectAuto);
</syntaxhighlight><syntaxhighlight lang="javascript" line="1" start="1138">
document.body.addEventListener("keydown", keydown_linkAuto);
</syntaxhighlight>
|-
|
|key up
|onKeyUp
|
|
|<syntaxhighlight lang="javascript" line="1" start="1164">
document.body.addEventListener("keyup", onKeyUp);
</syntaxhighlight>
|-
|w
|cursor Move
|updateCoordDisplay
|
|
|<syntaxhighlight lang="javascript" line="1" start="280">
w.on("cursorMove", updateCoordDisplay);
</syntaxhighlight>
|-
|
|cursor Hide
|updateCoordDisplay
|
|
|<syntaxhighlight lang="javascript" line="1" start="281">
w.on("cursorHide", updateCoordDisplay);
</syntaxhighlight>
|-
|
|tiles Rendered
|self
|
|
|<syntaxhighlight lang="javascript" line="1" start="4747">
w.on("tilesRendered", function() {
for(var i = 0; i < regionSelections.length; i++) {
var reg = regionSelections[i];
if(reg.regionCoordA && reg.regionCoordB) reg.setSelection(reg.regionCoordA, reg.regionCoordB);
}
});
</syntaxhighlight>
|-
|
|cursor Move
|setClientGuestCursorPosition
|
|
|<syntaxhighlight lang="javascript" line="1" start="4754">
w.on("cursorMove", function(pos) {
setClientGuestCursorPosition(pos.tileX, pos.tileY, pos.charX, pos.charY);
});
</syntaxhighlight>
|-
|
|cursor Hide
|setClientGuestCursorPosition
|
|
|<syntaxhighlight lang="javascript" line="1" start="4758">
w.on("cursorHide", function() {
setClientGuestCursorPosition(0, 0, 0, 0, true);
});
</syntaxhighlight>
|-
|elm.textInput
|
* keydown
* input
|
* stabilizeTextInput
* event_input
|
|
|<syntaxhighlight lang="javascript" line="1" start="2618">
elm.textInput.addEventListener("keydown", stabilizeTextInput);
elm.textInput.addEventListener("input", event_input);
</syntaxhighlight>
|-
|elm.owot
|context menu
|self
|
|
|<syntaxhighlight lang="javascript" line="1" start="5628">
elm.owot.oncontextmenu = function() {
if(ignoreCanvasContext) {
ignoreCanvasContext = false;
elm.owot.style.pointerEvents = "none";
setTimeout(function() {
ignoreCanvasContext = true;
elm.owot.style.pointerEvents = "";
}, 1);
}
}
</syntaxhighlight>
|-
|elm.coords
|click
|self
|
|
|<syntaxhighlight lang="javascript" line="1" start="283">
elm.coords.onclick = function() {
showCursorCoordinates = !showCursorCoordinates;
if(showCursorCoordinates) {
elm.cursor_coords.style.display = "";
updateCoordDisplay();
} else {
elm.cursor_coords.style.display = "none";
updateCoordDisplay();
}
}
</syntaxhighlight>
|}


===Functions:===
===Functions:===
 
{| class="wikitable"
*
|+
!Name
!Description
!Example Usage
!Code In Use
|-
|init_dom()
|
|
|<syntaxhighlight lang="javascript" line="1" start="11">
function init_dom() {
owot = document.getElementById("owot");
owot.style.display = "block";
owot.style.cursor = defaultCursor;
owotCtx = owot.getContext("2d");
textInput = document.getElementById("textInput");
textInput.value = "";
linkElm = elm.link_element;
linkDiv = elm.link_div;
updateCoordDisplay();
initTextDecoBar();
defineElements({
owot: owot,
textInput: textInput
});
}
</syntaxhighlight>
|-
|getWndWidth()
|
|
|<syntaxhighlight lang="javascript" line="1" start="27">
function getWndWidth() {
return document.body.clientWidth || window.innerWidth;
}
</syntaxhighlight>
|-
|getWndHeight()
|
|
|
|-
|decimal(percentage)
|
|
|
|-
|normFontSize(size)
|
|
|
|-
|deviceRatio()
|
|
|
|-
|makeEnum(vars)
|
|
|
|-
|setRGBColorPicker(r, g, b)
|
|
|
|-
|setRGBBgColorPicker(r, g, b)
|
|
|
|-
|setColorPickerRandom()
|
|
|
|-
|updateColorPicker()
|
|
|
|-
|updateBgColorPicker()
|
|
|
|-
|updateCoordDisplay()
|
|
|
|-
|createColorButton(color, isHighlight)
|
|
|
|-
|addColorShortcuts()
|
|
|
|-
|draggable_element(dragger, dragged, exclusions, onDrag)
|
|
|
|-
|resizeChat(width, height)
|
|
|
|-
|getStoredNickname()
|
|
|
|-
|storeNickname()
|
|
|
|-
|getStoredConfig()
|
|
|
|-
|storeConfig()
|
|
|
|-
|loadBackgroundData(cb, timeout_cb)
|
|
|
|-
|keydown_regionSelect(e)
|
|
|
|-
|handleRegionSelection(coordA, coordB, regWidth, regHeight)
|
|
|
|-
|buildFontTemplate(set)
|
|
|
|-
|rebuildFontTemplates()
|
|
|
|-
|updateScaleConsts()
|
|
|
|-
|setupTextRenderCtx()
|
|
|
|-
|reloadRenderer()
|
|
|
|-
|updateRendererZoom(percentage)
|
|
|
|-
|zoomGarbageCollect()
|
|
|
|-
|changeZoom(percentage, isPartial)
|
|
|
|-
|setZoombarValue()
|
|
|
|-
|fromLogZoom(val)
|
|
|
|-
|toLogZoom(val)
|
|
|
|-
|browserZoomAdjust(initial)
|
|
|
|-
|updateAutoProg()
|
|
|
|-
|mousemove_tileProtectAuto()
|
|
|
|-
|keydown_tileProtectAuto(e)
|
|
|
|-
|mousemove_linkAuto()
|
|
|
|-
|keydown_linkAuto(e)
|
|
|
|-
|onKeyUp(e)
|
|
|
|-
|adjust_scaling_DOM(ratio)
|
|
|
|-
|event_resize()
|
|
|
|-
|getChar(tileX, tileY, charX, charY)
|
|
|
|-
|getCharColor(tileX, tileY, charX, charY)
|
|
|
|-
|getCharBgColor(tileX, tileY, charX, charY)
|
|
|
|-
|getCharProtection(tileX, tileY, charX, charY)
|
|
|
|-
|getCharDecoration(tileX, tileY, charX, charY)
|
|
|
|-
|getCharInfo(tileX, tileY, charX, charY)
|
|
|
|-
|getCharInfoXY(x, y)
|
|
|
|-
|getLink(tileX, tileY, charX, charY)
|
|
|
|-
|getLinkXY(x, y)
|
|
|
|-
|event_keydown_copy_char(e)
|
|
|
|-
|event_keydown_copy_color(e)
|
|
|
|-
|resolveColorValue(val)
|
|
|
|-
|isTileStale(tileX, tileY)
|
|
|
|-
|checkTextColorOverride()
|
|
|
|-
|menu_color(color)
|
|
|
|-
|defaultStyles()
|
|
|
|-
|manageCoordHash()
|
|
|
|-
|getWorldProps(world, type, cb)
|
|
|
|-
|stopLinkUI()
|
|
|
|-
|removeTileProtectHighlight()
|
|
|
|-
|stopTileUI()
|
|
|
|-
|doLink()
|
|
|
|-
|doProtect()
|
|
|
|-
|triggerUIClick()
|
|
|
|-
|event_mousedown(e, arg_pageX, arg_pageY)
|
|
|
|-
|renderCursor(coords)
|
|
|
|-
|removeCursor()
|
|
|
|-
|stopDragging()
|
|
|
|-
|event_mouseup(e, arg_pageX, arg_pageY)
|
|
|
|-
|event_mouseleave(e)
|
|
|
|-
|event_mouseenter(e)
|
|
|
|-
|is_link(tileX, tileY, charX, charY)
|
|
|
|-
|flushWrites()
|
|
|
|-
|setWriteInterval()
|
|
|
|-
|moveCursor(direction, preserveVertPos, amount)
|
|
|
|-
|markCharacterAsUndoable(tileX, tileY, charX, charY)
|
|
|
|-
|isCharLatestInUndoBuffer(tileX, tileY, charX, charY)
|
|
|
|-
|writeCharTo(char, charColor, tileX, tileY, charX, charY, undoFlags, undoOffset, charBgColor, dB, dI, dU, dS)
|
|
|
|-
|undoWrite()
|
|
|
|-
|redoWrite()
|
|
|
|-
|writeCharToXY(char, charColor, x, y, charBgColor, dB, dI, dU, dS)
|
|
|
|-
|writeChar(char, doNotMoveCursor, color, noNewline, undoCursorOffset, bgColor, dB, dI, dU, dS)
|
|
|
|-
|coordinateAdd(tileX1, tileY1, charX1, charY1, tileX2, tileY2, charX2, charY2)
|
|
|
|-
|propagatePosition(coords, char, noEnter, noVertPos)
|
|
|
|-
|textcode_parser(value, coords, defaultColor, defaultBgColor)
|
|
|
|-
|stabilizeTextInput()
|
|
|
|-
|event_input(e)
|
|
|
|-
|stopPasting()
|
|
|
|-
|autoArrowKeyMoveStart(dir)
|
|
|
|-
|autoArrowKeyMoveStop(dir)
|
|
|
|-
|event_keydown(e)
|
|
|
|-
|event_keyup(e)
|
|
|
|-
|isMainPage()
|
|
|
|-
|alertJS(data, restrict)
|
|
|
|-
|closeJSAlert()
|
|
|
|-
|executeJS(code)
|
|
|
|-
|confirmRunJSLink(data)
|
|
|
|-
|runJSLink(data, restrict)
|
|
|
|-
|coord_link_click(evt)
|
|
|
|-
|url_link_click(evt)
|
|
|
|-
|updateHoveredLink(mouseX, mouseY, evt, safe)
|
|
|
|-
|event_mousemove(e, arg_pageX, arg_pageY)
|
|
|
|-
|getCenterTouchPosition(touches)
|
|
|
|-
|event_touchstart(e)
|
|
|
|-
|event_touchend(e)
|
|
|
|-
|event_touchmove(e)
|
|
|
|-
|touch_pagePos(e)
|
|
|
|-
|event_wheel(e)
|
|
|
|-
|event_wheel_zoom(e)
|
|
|
|-
|convertKeyCode(key)
|
|
|
|-
|checkKeyPress(e, combination)
|
|
|
|-
|checkKeyPatterns(combination)
|
|
|
|-
|createWsPath()
|
|
|
|-
|createSocket(getChatHist)
|
|
|
|-
|cullRanges(map, width, height)
|
|
|
|-
|updateRemoteBoundary()
|
|
|
|-
|clearRemoteBoundary()
|
|
|
|-
|expandLocalBoundary(x, y)
|
|
|
|-
|getAndFetchTiles()
|
|
|
|-
|clearTiles(all)
|
|
|
|-
|clearVisibleTiles()
|
|
|
|-
|highlight(positions, unlimited, color)
|
|
|
|-
|blankTile()
|
|
|
|-
|colorChar(tileX, tileY, charX, charY, colorClass)
|
|
|
|-
|uncolorChar(tileX, tileY, charX, charY, colorClass)
|
|
|
|-
|decodeCharProt(str)
|
|
|
|-
|encodeCharProt(array, encoding)
|
|
|
|-
|getCharTextDecorations(char)
|
|
|
|-
|setCharTextDecorations(char, bold, italic, under, strike)
|
|
|
|-
|resolveCharEmojiCombinations(char)
|
|
|
|-
|detectCharEmojiCombinations(char)
|
|
|
|-
|clearCharTextDecorations(char)
|
|
|
|-
|clearAllGuestCursors()
|
|
|
|-
|renderLoop()
|
|
|
|-
|protectPrecisionOption(option)
|
|
|
|-
|toggleTextDecoBar()
|
|
|
|-
|initTextDecoBar()
|
|
|
|-
|protectSelectionStart(start, end, width, height)
|
|
|
|-
|protectSelectionCancel()
|
|
|
|-
|protectSelection()
|
|
|
|-
|buildMenu()
|
|
|
|-
|updateMenuEntryVisiblity()
|
|
|
|-
|regionSelectionsActive()
|
|
|
|-
|RegionSelection()
|
|
|
|-
|setClientGuestCursorPosition(tileX, tileY, charX, charY, hidden)
|
|
|
|-
|sendCursorPosition()
|
|
|
|-
|disableBgColorPicker()
|
|
|
|-
|enableBgColorPicker()
|
|
|
|-
|makeCoordLinkModal()
|
|
|
|-
|makeCoordGotoModal()
|
|
|
|-
|makeURLModal()
|
|
|
|-
|buildBackgroundColorModal(modal)
|
|
|
|-
|resetColorModalVisibility()
|
|
|
|-
|makeColorModal()
|
|
|
|-
|makeSelectionModal()
|
|
|
|-
|searchTellEdit(tileX, tileY, charX, charY)
|
|
|
|-
|tile_offset_object(data, tileOffX, tileOffY)
|
|
|
|-
|begin()
|
|
|
|}


===Variables:===
===Variables:===
Line 15: Line 1,193:
!Description
!Description
!Example Usage
!Example Usage
!Code
!Code In Use
|-
|-
|YourWorld
|YourWorld
Line 226: Line 1,404:
|<syntaxhighlight lang="javascript" line="1" start="61">
|<syntaxhighlight lang="javascript" line="1" start="61">
var nextObjId = 1;
var nextObjId = 1;
</syntaxhighlight>
|-
|owotWidth,
owotHeight
|The current width and height of the DOM window.
|<syntaxhighlight lang="javascript">
//Estimate the total number of fully visible cells that could exist on the screen
const cellAmount = Math.floor(owotHeight/cellH * owotWidth/cellW);
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="1170">
owotWidth = Math.round(window_width * ratio);
owotHeight = Math.round(window_height * ratio);
</syntaxhighlight>
|-
|js_alert_active
|A bool stating if the javascript alert window is open.
|
|<syntaxhighlight lang="javascript" line="1" start="64">
var js_alert_active = false;
</syntaxhighlight>
|-
|worldFocused
|A bool stating if the owot canvas is in focus.
|<syntaxhighlight lang="javascript">
//check every 100ms if the owot canvas was last clicked, if it was then randomly change the public tile color.
setInterval(function() {
  if (worldFocused) {
    styles.public = "#" + Math.floor(Math.random() * 16777215).toString(16).toUpperCase();
    w.redraw()
  }
}, 100)
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="1737">
if(closest(target, getChatfield()) || target == elm.chatbar || target == elm.confirm_js_code) {
worldFocused = false;
} else {
worldFocused = true;
}
</syntaxhighlight>
|-
|chatResizing
|A bool stating if the chat window is being resized.
|<syntaxhighlight lang="javascript">
//check every 100ms if the chat is resizing, if it is, change the public tile color
setInterval(function() {
  if (chatResizing) {
    styles.public = "#" + Math.floor(Math.random() * 16777215).toString(16).toUpperCase();
    w.redraw()
  }
}, 100)
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="441">
draggable_element(elm.chat_window, null, [
elm.chatbar, elm.chatsend, elm.chat_close, elm.chat_page_tab, elm.chat_global_tab, elm.page_chatfield, elm.global_chatfield
], function() {
if(chatResizing) {
return -1;
}
});
</syntaxhighlight>
|-
|tiles
|An object containing all the loaded tiles.
|<syntaxhighlight lang="javascript">
//Return any visible links
const [X,Y] = cursorCoords;
tiles[`${X},${Y}`].properties.cell_props
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="1416">
Tile.set = function(tileX, tileY, data) {
var str = tileY + "," + tileX;
if(!(str in tiles)) {
w.tile.count++;
}
tiles[str] = data;
expandLocalBoundary(tileX, tileY);
return data;
}
</syntaxhighlight>
|-
|images,
keysPressed,
imgPatterns
|Empty, unused objects.
|
|<syntaxhighlight lang="javascript" line="1" start="68">
var images = {};
var keysPressed = {};
</syntaxhighlight>
|-
|previousErase
|An integer of the last date the erase function was utilised.
|<syntaxhighlight lang="javascript">
//Logs the previous erase time in a human-readable way.
function readPreviousErase() {
  if (previousErase == 0) {
    return
  }
  const date = new Date(previousErase);
  const options = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    timeZoneName: 'short'
  };
  console.log("last Erased at:", date.toLocaleString(undefined, options));
}
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="2608">
function event_input(e) {
if(e.inputType == "deleteContentBackward") {
if(getDate() - previousErase > 25 || !previousErase) {
moveCursor("left", true);
writeChar("\x08", true, null, false, 1);
}
previousErase = getDate();
}
}
</syntaxhighlight>
|-
|verticalEnterPos
|A 2D array coordinate of the position to go when pressing enter.
|<syntaxhighlight lang="javascript">
//Stair-step the return position on "enter"
textInput.addEventListener("input", function(e) {
  if (e.inputType === "insertLineBreak") {
    const [X, x] = verticalEnterPos;
    verticalEnterPos = [X, (x + 1) % 16]
  }
})
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="2352">
if(noVertPos) {
coords.tileX = 0;
coords.charX = 0;
} else {
coords.tileX = verticalEnterPos[0];
coords.charX = verticalEnterPos[1];
}
</syntaxhighlight>
|-
|textColorOverride
|public-member-owner bitfield used to modify the text color in fields.
|
|<syntaxhighlight lang="javascript" line="1" start="1477">
if(styles.public_text != "#000" && styles.public_text != "#000000") {
textColorOverride |= public;
} else {
textColorOverride &= textColorOverride ^ public;
}
</syntaxhighlight>
|-
|writeBuffer
|An object holding data waiting to be rendered to the canvas.
|<syntaxhighlight lang="javascript">
//Writes the character "█" at the cursorCoords location
const [tileX, tileY, charX, charY] = cursorCoords;
const editArray = [tileY, tileX, charY, charX, getDate(), "█", nextObjId++]
writeBuffer.push(editArray);
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="2179">
tellEdit.push(editArray); // track local changes
writeBuffer.push(editArray); // send edits to server
nextObjId++;
</syntaxhighlight>
|-
|highlightFlash
|An object containing cell coordinates of cells to be highlighted.
|<syntaxhighlight lang="javascript">
//Flashes a random color on all visible cells
function flashRandom() {
  const visibleTiles = getVisibleTiles();
  const color = [Math.floor(Math.random() * 256), Math.floor(Math.random() * 256), Math.floor(Math.random() * 256)];
  const positions = [];
  // Generate the positions array
  for (const [tileX, tileY] of visibleTiles) {
    for (let charY = 0; charY < 8; charY++) {
      for (let charX = 0; charX < 16; charX++) {
        positions.push([tileX, tileY, charX, charY]);
      }
    }
  }
  // Update highlightFlash based on positions
  for (const [tileX, tileY, charX, charY] of positions) {
    const tileKey = `${tileY},${tileX}`;
    highlightFlash[tileKey] ??= {};
    highlightFlash[tileKey][charY] ??= {};
    if (!highlightFlash[tileKey][charY][charX]) {
      highlightFlash[tileKey][charY][charX] = [getDate(), color, [...color]];
      highlightCount++;
    }
  }
}
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="3988">
if(!highlightFlash[tileY + "," + tileX]) {
highlightFlash[tileY + "," + tileX] = {};
}
</syntaxhighlight>
|-
|highlightCount
|An iterator used to limit the amount of highlights rendered to the canvas.
|<syntaxhighlight lang="javascript">
//Prevents the user from seeing highlights
highlightCount = Infinity;
</syntaxhighlight>
|<syntaxhighlight lang="javascript" line="1" start="3987">
if(highlightCount > highlightLimit && !unlimited) return;
</syntaxhighlight>
|-
|coloredChars
|An object holding all of the highlighted characters.
|
|<syntaxhighlight lang="javascript" line="1" start="4071">
var container = coloredChars[tileY + "," + tileX];
if(!container) {
container = {};
coloredChars[tileY + "," + tileX] = container;
}
</syntaxhighlight>
|-
|shiftOptState
|An object used to store the viewport values
|
|<syntaxhighlight lang="javascript" line="1" start="79">
var shiftOptState = { prevX: 0, prevY: 0, x1: 0, y1: 0, x2: 0, y2: 0, prevZoom: -1 };
</syntaxhighlight>
|-
|backgroundImage
|
|
|
|-
|backgroundPattern
|
|
|
|
|-
|backgroundPatternSize
|
|
|
|-
|guestCursorsByTile
|
|
|
|
|-
|guestCursors
|
|
|
|-
|clientGuestCursorPos
|
|
|
|
|-
|disconnectTimeout
|
|
|
|-
|menuOptions
|
|
|
|
|-
|undoBuffer
|
|
|
|-
|textDecorationOffset
|
|
|
|
|-
|textDecorationModes
|
|
|
|-
|fontTemplate
|
|
|
|
|-
|specialFontTemplate
|
|
|
|-
|fontOrder
|
|
|
|
|-
|specialFontOrder
|
|
|
|-
|initiallyFetched
|
|
|
|
|-
|lastLinkHover
|
|
|
|-
|lastTileHover
|
|
|
|
|-
|regionSelections
|
|
|
|-
|specialClientHooks
|
|
|
|
|-
|specialClientHookMap
|
|
|
|-
|bgImageHasChanged
|
|
|
|
|-
|remoteBoundary
|
|
|
|-
|boundaryStatus
|
|
|
|
|-
|positionX
|
|
|
|-
|positionY
|
|
|
|
|-
|coordSizeX
|
|
|
|-
|coordSizeY
|
|
|
|
|-
|gridEnabled
|
|
|
|-
|subgridEnabled
|
|
|
|
|-
|linksEnabled
|
|
|
|-
|linksRendered
|
|
|
|
|-
|colorsEnabled
|
|
|
|-
|backgroundEnabled
|
|
|
|
|-
|scrollingEnabled
|
|
|
|-
|zoomRatio
|
|
|
|-
|protectPrecision
|
|
|
|-
|checkTileFetchInterval
|
|
|
|
|-
|zoom
|
|
|
|-
|userZoom
|
|
|
|-
|unloadTilesAuto
|
|
|
|
|-
|useHighlight
|
|
|
|-
|highlightLimit
|
|
|
|-
|ansiBlockFill
|
|
|
|
|-
|colorizeLinks
|
|
|
|-
|brBlockFill
|
|
|
|-
|tileFetchOffsetX
|
|
|
|
|-
|tileFetchOffsetY
|
|
|
|-
|ignoreCanvasContext
|
|
|
|-
|elementSnapApprox
|
|
|
|
|-
|mSpecRendering
|
|
|
|-
|combiningCharsEnabled
|
|
|
|-
|surrogateCharsEnabled
|
|
|
|
|-
|defaultCoordLinkColor
|
|
|
|-
|defaultURLLinkColor
|
|
|
|-
|defaultHighlightColor
|
|
|
|
|-
|secureJSLink
|
|
|
|-
|secureLink
|
|
|
|-
|pasteDirRight
|
|
|
|
|-
|pasteDirDown
|
|
|
|-
|defaultCursor
|
|
|
|-
|defaultDragCursor
|
|
|
|
|-
|fetchClientMargin
|
|
|
|-
|classicTileProcessing
|
|
|
|-
|unloadedPatternPanning
|
|
|
|
|-
|cursorRenderingEnabled
|
|
|
|-
|guestCursorsEnabled
|
|
|
|-
|showMyGuestCursor
|
|
|
|
|-
|unobstructCursor
|
|
|
|-
|shiftOptimization
|
|
|
|-
|transparentBackground
|
|
|
|
|-
|writeFlushRate
|
|
|
|-
|bufferLargeChars
|
|
|
|-
|cursorOutlineEnabled
|
|
|
|-
|showCursorCoordinates
|
|
|
|-
|textDecorationsEnabled
|
|
|
|-
|keyConfig
|
|
|
|-
|draggable_element_mousemove
|
|
|
|-
|draggable_element_mouseup
|
|
|
|
|-
|defaultSizes
|
|
|
|
|-
|cellWidthPad
|
|
|
|
|-
|tileW
|
|
|
|
|-
|tileH
|
|
|
|
|-
|cellW
|
|
|
|
|-
|cellH
|
|
|
|
|-
|font
|
|
|
|
|-
|specialCharFont
|
|
|
|
|-
|tileC
|
|
|
|
|-
|tileR
|
|
|
|
|-
|tileArea
|
|
|
|
|-
|tileWidth
|
|
|
|
|-
|tileHeight
|
|
|
|
|-
|dTileW
|
|
|
|
|-
|dTileH
|
|
|
|
|-
|textRenderCanvas
|
|
|
|
|-
|textRenderCtx
|
|
|
|
|-
|tileProtectAuto
|
|
|
|
|-
|linkAuto
|
|
|
|
|-
|autoTotal
|
|
|
|
|-
|cursorCoords
|
|
|
|
|-
|cursorCoordsCurrent
|
|
|
|
|-
|currentPosition
|
|
|
|
|-
|currentPositionInitted
|
|
|
|
|-
|currentMousePosition
|
|
|
|
|-
|Tile
|
|
|
|
|-
|poolCleanupInterval
|
|
|
|
|-
|dragStartX
|
|
|
|
|-
|dragStartY
|
|
|
|
|-
|dragPosX
|
|
|
|
|-
|dragPosY
|
|
|
|
|-
|isDragging
|
|
|
|
|-
|hasDragged
|
|
|
|
|-
|draggingEnabled
|
|
|
|
|-
|cursorEnabled
|
|
|
|
|-
|writeInterval
|
|
|
|
|-
|write_busy
|
|
|
|
|-
|pasteInterval
|
|
|
|
|-
|linkQueue
|
|
|
|
|-
|autoArrowKeyMoveInterval
|
|
|
|
|-
|autoArrowKeyMoveActive
|
|
|
|
|-
|autoArrowKeyMoveState
|
|
|
|
|-
|linkParams
|
|
|
|
|-
|currentSelectedLink
|
|
|
|
|-
|currentSelectedLinkCoords
|
|
|
|
|-
|touchInitZoom
|
|
|
|
|-
|touchInitDistance
|
|
|
|
|-
|touchPrev
|
|
|
|
|-
|fetchInterval
|
|
|
|
|-
|timesConnected
|
|
|
|
|-
|colorClasses
|
|
|
|
|-
|isTileLoaded
|
|
|
|
|-
|isTileVisible
|
|
|
|
|-
|networkHTTP
|
|
|
|
|-
|network
|
|
|
|
|-
|w
|
|
|
|
|-
|tellEdit
|
|
|
|
|-
|ws_functions
|
|
|
|
|}
== chat.js ==
=== Event listeners ===
{| class="wikitable"
!Object
!Listen Event
!Functions/Events Fired
!Emits
!Example Usage
!Related Code
|-
|elm.chatsend
|click
|sendChat()
|
|
|<syntaxhighlight lang="javascript" line="1" start="260">
elm.chatsend.addEventListener("click", function() {
sendChat();
});
</syntaxhighlight>
|-
|elm.chatbar
|keypress
|var keyCode = e.keyCode;
if(keyCode == 13) {
sendChat();
}
|
|
|<syntaxhighlight lang="javascript" line="1" start="264">
elm.chatbar.addEventListener("keypress", function(e) {
var keyCode = e.keyCode;
if(keyCode == 13) { // Enter
sendChat();
}
});
</syntaxhighlight>
|-
|elm.chatbar
|keydown
|var keyCode = e.keyCode;
// scroll through chat history that the client sent
if(keyCode == 38) { // up
// history modified
if(chatWriteHistoryIdx > -1 && elm.chatbar.value != chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1]) {
chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1] = elm.chatbar.value;
}
if(chatWriteHistoryIdx == -1 && elm.chatbar.value) {
chatWriteTmpBuffer = elm.chatbar.value;
}
chatWriteHistoryIdx++;
if(chatWriteHistoryIdx >= chatWriteHistory.length) chatWriteHistoryIdx = chatWriteHistory.length - 1;
var upVal = chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1];
if(!upVal) return;
elm.chatbar.value = upVal;
// pressing up will move the cursor all the way to the left by default
e.preventDefault();
moveCaretEnd(elm.chatbar);
} else if(keyCode == 40) { // down
// history modified
if(chatWriteHistoryIdx > -1 && elm.chatbar.value != chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1]) {
chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1] = elm.chatbar.value;
}
chatWriteHistoryIdx--;
if(chatWriteHistoryIdx < -1) {
chatWriteHistoryIdx = -1;
return;
}
var str = "";
if(chatWriteHistoryIdx != -1) {
str = chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1];
} else {
if(chatWriteTmpBuffer) {
str = chatWriteTmpBuffer;
e.preventDefault();
moveCaretEnd(elm.chatbar);
}
}
elm.chatbar.value = str;
e.preventDefault();
moveCaretEnd(elm.chatbar);
}
|
|
|<syntaxhighlight lang="javascript" line="1" start="283">
elm.chatbar.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;
// scroll through chat history that the client sent
if(keyCode == 38) { // up
// history modified
if(chatWriteHistoryIdx > -1 && elm.chatbar.value != chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1]) {
chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1] = elm.chatbar.value;
}
if(chatWriteHistoryIdx == -1 && elm.chatbar.value) {
chatWriteTmpBuffer = elm.chatbar.value;
}
chatWriteHistoryIdx++;
if(chatWriteHistoryIdx >= chatWriteHistory.length) chatWriteHistoryIdx = chatWriteHistory.length - 1;
var upVal = chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1];
if(!upVal) return;
elm.chatbar.value = upVal;
// pressing up will move the cursor all the way to the left by default
e.preventDefault();
moveCaretEnd(elm.chatbar);
} else if(keyCode == 40) { // down
// history modified
if(chatWriteHistoryIdx > -1 && elm.chatbar.value != chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1]) {
chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1] = elm.chatbar.value;
}
chatWriteHistoryIdx--;
if(chatWriteHistoryIdx < -1) {
chatWriteHistoryIdx = -1;
return;
}
var str = "";
if(chatWriteHistoryIdx != -1) {
str = chatWriteHistory[chatWriteHistory.length - chatWriteHistoryIdx - 1];
} else {
if(chatWriteTmpBuffer) {
str = chatWriteTmpBuffer;
e.preventDefault();
moveCaretEnd(elm.chatbar);
}
}
elm.chatbar.value = str;
e.preventDefault();
moveCaretEnd(elm.chatbar);
}
});
</syntaxhighlight>
|-
|elm.chat_close
|click
|w.emit("chatClose");
elm.chat_window.style.display = "none";
elm.chat_open.style.display = "";
chatOpen = false;
|"chatClose"
|
|<syntaxhighlight lang="javascript" line="1" start="328">
elm.chat_close.addEventListener("click", function() {
w.emit("chatClose");
elm.chat_window.style.display = "none";
elm.chat_open.style.display = "";
chatOpen = false;
});
</syntaxhighlight>
|-
|elm.chat_open
|click
|elm.chat_window.style.display = "";
elm.chat_open.style.display = "none";
chatOpen = true;
if(selectedChatTab == 0) {
chatPageUnread = 0;
updateUnread();
if(!initPageTabOpen) {
initPageTabOpen = true;
elm.page_chatfield.scrollTop = elm.page_chatfield.scrollHeight;
}
} else {
chatGlobalUnread = 0;
updateUnread();
if(!initGlobalTabOpen) {
initGlobalTabOpen = true;
elm.global_chatfield.scrollTop = elm.global_chatfield.scrollHeight;
}
}
var chatWidth = chat_window.offsetWidth - 2;
var chatHeight = chat_window.offsetHeight - 2;
var screenRatio = window.devicePixelRatio;
if(!screenRatio) screenRatio = 1;
var virtWidth = owotWidth / screenRatio;
if(chatWidth > virtWidth) {
resizeChat(virtWidth - 2, chatHeight);
}
|"chatOpen"
|
|<syntaxhighlight lang="javascript" line="1" start="335">
elm.chat_open.addEventListener("click", function() {
w.emit("chatOpen");
elm.chat_window.style.display = "";
elm.chat_open.style.display = "none";
chatOpen = true;
if(selectedChatTab == 0) {
chatPageUnread = 0;
updateUnread();
if(!initPageTabOpen) {
initPageTabOpen = true;
elm.page_chatfield.scrollTop = elm.page_chatfield.scrollHeight;
}
} else {
chatGlobalUnread = 0;
updateUnread();
if(!initGlobalTabOpen) {
initGlobalTabOpen = true;
elm.global_chatfield.scrollTop = elm.global_chatfield.scrollHeight;
}
}
var chatWidth = chat_window.offsetWidth - 2;
var chatHeight = chat_window.offsetHeight - 2;
var screenRatio = window.devicePixelRatio;
if(!screenRatio) screenRatio = 1;
var virtWidth = owotWidth / screenRatio;
if(chatWidth > virtWidth) {
resizeChat(virtWidth - 2, chatHeight);
}
});
</syntaxhighlight>
|-
|elm.chat_page_tab
|click
|elm.chat_page_tab.classList.add("chat_tab_selected");
elm.chat_global_tab.classList.remove("chat_tab_selected");
elm.global_chatfield.style.display = "none";
elm.page_chatfield.style.display = "";
selectedChatTab = 0;
chatPageUnread = 0;
updateUnread();
if(!initPageTabOpen) {
initPageTabOpen = true;
elm.page_chatfield.scrollTop = elm.page_chatfield.scrollHeight;
}
|
|
|<syntaxhighlight lang="js" line="1" start="365">
elm.chat_page_tab.addEventListener("click", function() {
elm.chat_page_tab.classList.add("chat_tab_selected");
elm.chat_global_tab.classList.remove("chat_tab_selected");
elm.global_chatfield.style.display = "none";
elm.page_chatfield.style.display = "";
selectedChatTab = 0;
chatPageUnread = 0;
updateUnread();
if(!initPageTabOpen) {
initPageTabOpen = true;
elm.page_chatfield.scrollTop = elm.page_chatfield.scrollHeight;
}
});
</syntaxhighlight>
|-
|elm.chat_global_tab
|click
|elm.chat_global_tab.classList.add("chat_tab_selected");
elm.chat_page_tab.classList.remove("chat_tab_selected");
elm.global_chatfield.style.display = "";
elm.page_chatfield.style.display = "none";
selectedChatTab = 1;
chatGlobalUnread = 0;
updateUnread();
if(!initGlobalTabOpen) {
initGlobalTabOpen = true;
elm.global_chatfield.scrollTop = elm.global_chatfield.scrollHeight;
}
|
|
|<syntaxhighlight lang="js" line="1" start="380">
elm.chat_global_tab.addEventListener("click", function() {
elm.chat_global_tab.classList.add("chat_tab_selected");
elm.chat_page_tab.classList.remove("chat_tab_selected");
elm.global_chatfield.style.display = "";
elm.page_chatfield.style.display = "none";
selectedChatTab = 1;
chatGlobalUnread = 0;
updateUnread();
if(!initGlobalTabOpen) {
initGlobalTabOpen = true;
elm.global_chatfield.scrollTop = elm.global_chatfield.scrollHeight;
}
});
</syntaxhighlight>
|-
|chat_window
|mousemove
|if(isDown) return;
var posX = e.pageX - chat_window.offsetLeft;
var posY = e.pageY - chat_window.offsetTop;
var top = (posY) <= 4;
var left = (posX) <= 3;
var right = (chat_window.offsetWidth - posX) <= 4;
var bottom = (chat_window.offsetHeight - posY) <= 5;
var cursor = "";
if(left || right) cursor = "ew-resize";
if(top || bottom) cursor = "ns-resize";
if((top && left) || (right && bottom)) cursor = "nwse-resize";
if((bottom && left) || (top && right)) cursor = "nesw-resize";
chat_window.style.cursor = cursor;
state = bottom << 3 | right << 2 | left << 1 | top;
|
|
|<syntaxhighlight lang="js" line="1" start="404">
chat_window.addEventListener("mousemove", function(e) {
if(isDown) return;
var posX = e.pageX - chat_window.offsetLeft;
var posY = e.pageY - chat_window.offsetTop;
var top = (posY) <= 4;
var left = (posX) <= 3;
var right = (chat_window.offsetWidth - posX) <= 4;
var bottom = (chat_window.offsetHeight - posY) <= 5;
var cursor = "";
if(left || right) cursor = "ew-resize";
if(top || bottom) cursor = "ns-resize";
if((top && left) || (right && bottom)) cursor = "nwse-resize";
if((bottom && left) || (top && right)) cursor = "nesw-resize";
chat_window.style.cursor = cursor;
state = bottom << 3 | right << 2 | left << 1 | top;
});
</syntaxhighlight>
|-
|chat_window
|mousedown
|downX = e.pageX;
downY = e.pageY;
if(state) {
// subtract 2 for the borders
chatWidth = chat_window.offsetWidth - 2;
chatHeight = chat_window.offsetHeight - 2;
elmX = chat_window.offsetLeft;
elmY = chat_window.offsetTop;
isDown = true;
chatResizing = true;
}
|
|
|<syntaxhighlight lang="js" line="1" start="420">
chat_window.addEventListener("mousedown", function(e) {
downX = e.pageX;
downY = e.pageY;
if(state) {
// subtract 2 for the borders
chatWidth = chat_window.offsetWidth - 2;
chatHeight = chat_window.offsetHeight - 2;
elmX = chat_window.offsetLeft;
elmY = chat_window.offsetTop;
isDown = true;
chatResizing = true;
}
});
</syntaxhighlight>
|-
|document
|mouseup
|isDown = false;
chatResizing = false;
|
|
|<syntaxhighlight lang="js" line="1" start="433">
document.addEventListener("mouseup", function() {
isDown = false;
chatResizing = false;
});
</syntaxhighlight>
|-
|document
|mousemove
|if(!isDown) return;
var offX = e.pageX - downX;
var offY = e.pageY - downY;
var resize_bottom = state >> 3 & 1;
var resize_right = state >> 2 & 1;
var resize_left = state >> 1 & 1;
var resize_top = state & 1;
var width_delta = 0;
var height_delta = 0;
var abs_top = chat_window.offsetTop;
var abs_left = chat_window.offsetLeft;
var snap_bottom = chat_window.style.bottom == "0px";
var snap_right = chat_window.style.right == "0px";
if(resize_top) {
height_delta = -offY;
} else if(resize_bottom) {
height_delta = offY;
}
if(resize_left) {
width_delta = -offX;
} else if(resize_right) {
width_delta = offX;
}
var res = resizeChat(chatWidth + width_delta, chatHeight + height_delta);
if(resize_top && !snap_bottom) {
chat_window.style.top = (elmY + (chatHeight - res[1])) + "px";
}
if(resize_bottom && snap_bottom) {
chat_window.style.bottom = "";
chat_window.style.top = abs_top + "px";
}
if(resize_right && snap_right) {
chat_window.style.right = "";
chat_window.style.left = abs_left + "px";
}
if(resize_left && !snap_right) {
chat_window.style.left = (elmX + (chatWidth - res[0])) + "px";
}
|
|
|<syntaxhighlight lang="js" line="1" start="437">
document.addEventListener("mousemove", function(e) {
if(!isDown) return;
var offX = e.pageX - downX;
var offY = e.pageY - downY;
var resize_bottom = state >> 3 & 1;
var resize_right = state >> 2 & 1;
var resize_left = state >> 1 & 1;
var resize_top = state & 1;
var width_delta = 0;
var height_delta = 0;
var abs_top = chat_window.offsetTop;
var abs_left = chat_window.offsetLeft;
var snap_bottom = chat_window.style.bottom == "0px";
var snap_right = chat_window.style.right == "0px";
if(resize_top) {
height_delta = -offY;
} else if(resize_bottom) {
height_delta = offY;
}
if(resize_left) {
width_delta = -offX;
} else if(resize_right) {
width_delta = offX;
}
var res = resizeChat(chatWidth + width_delta, chatHeight + height_delta);
if(resize_top && !snap_bottom) {
chat_window.style.top = (elmY + (chatHeight - res[1])) + "px";
}
if(resize_bottom && snap_bottom) {
chat_window.style.bottom = "";
chat_window.style.top = abs_top + "px";
}
if(resize_right && snap_right) {
chat_window.style.right = "";
chat_window.style.left = abs_left + "px";
}
if(resize_left && !snap_right) {
chat_window.style.left = (elmX + (chatWidth - res[0])) + "px";
}
});
</syntaxhighlight>
|}
=== Functions ===
{| class="wikitable"
!Name
!Description
!Example usage
!Related code
|-
|api_chat_send(message,opts)
|Sends a chat message from the user running code
|<syntaxhighlight lang="js">
api_chat_send("Hello!",{nick:"nickname"});
</syntaxhighlight>
|<syntaxhighlight lang="js" line="1" start="75">
function api_chat_send(message, opts) {
if(!message) return;
if(!opts) opts = {};
var exclude_commands = opts.exclude_commands;
var nick = opts.nick || YourWorld.Nickname || state.userModel.username;
var location = opts.location ? opts.location : (selectedChatTab == 0 ? "page" : "global");
var msgLim = state.userModel.is_staff ? 3030 : 400;
message = message.trim();
if(!message.length) return;
message = message.slice(0, msgLim);
chatWriteHistory.push(message);
if(chatWriteHistory.length > chatWriteHistoryMax) {
chatWriteHistory.shift();
}
chatWriteHistoryIdx = -1;
chatWriteTmpBuffer = "";
var chatColor;
if(!opts.color) {
if(!YourWorld.Color) {
chatColor = assignColor(nick);
} else {
chatColor = "#" + ("00000" + YourWorld.Color.toString(16)).slice(-6);
}
} else {
chatColor = opts.color;
}
if(!exclude_commands && message.startsWith("/")) {
var args = message.substr(1).split(" ");
var command = args[0].toLowerCase();
args.shift();
if(client_commands.hasOwnProperty(command)) {
client_commands[command](args);
return;
}
}
network.chat(message, location, nick, chatColor);
}
</syntaxhighlight>
|-
|clientChatResponse(message)
|Creates a client-side message only visible to you
|<syntaxhighlight lang="js">
clientChatResponse("This is a client message.");
</syntaxhighlight>
|<syntaxhighlight lang="js" line="1" start="118">
function clientChatResponse(message) {
addChat(null, 0, "user", "[ Client ]", message, "Client", false, false, false, null, getDate());
}
</syntaxhighlight>
|-
|sendChat()
|Sends whatever is in the chat textbox to chat.
|<syntaxhighlight lang="js">
sendChat();
</syntaxhighlight>
|<syntaxhighlight lang="js" line="1" start="216">
function sendChat() {
var chatText = elm.chatbar.value;
elm.chatbar.value = "";
var opts = {};
if(defaultChatColor != null) {
opts.color = "#" + ("00000" + defaultChatColor.toString(16)).slice(-6);
}
api_chat_send(chatText, opts);
}
</syntaxhighlight>
|-
|updateUnread()
|Updates the unread messages counter when chat is closed.
|
|<syntaxhighlight lang="js" line="1" start="226">
function updateUnread() {
var total = elm.total_unread;
var page = elm.page_unread;
var global = elm.global_unread;
var totalCount = chatPageUnread + chatGlobalUnread;
total.style.display = "none";
global.style.display = "none";
page.style.display = "none";
if(totalCount) {
total.style.display = "";
total.innerText = totalCount > 99 ? "99+" : "(" + totalCount + ")";
}
if(chatPageUnread) {
page.style.display = "";
page.innerText = chatPageUnread > 99 ? "99+" : "(" + chatPageUnread + ")";
}
if(chatGlobalUnread) {
global.style.display = "";
global.innerText = chatGlobalUnread > 99 ? "99+" : "(" + chatGlobalUnread + ")";
}
}
</syntaxhighlight>
|-
|event_on_chat(data)
|Updates the unread messages counter for either global chat or the current page.
|
|<syntaxhighlight lang="js" line="1" start="248">
function event_on_chat(data) {
if((!chatOpen || selectedChatTab == 1) && data.location == "page") {
chatPageUnread++;
}
if((!chatOpen || selectedChatTab == 0) && data.location == "global" && !state.worldModel.no_chat_global) {
chatGlobalUnread++;
}
updateUnread();
addChat(data.location, data.id, data.type,
data.nickname, data.message, data.realUsername, data.op, data.admin, data.staff, data.color, data.date || Date.now(), data.dataObj);
}
</syntaxhighlight>
|-
|moveCaretEnd(elm)
|Moves the text cursor to the end of the chat message you want to type in the textbox.
|
|<syntaxhighlight lang="js" line="1" start="271">
function moveCaretEnd(elm) {
if(elm.selectionStart != void 0) {
elm.selectionStart = elm.value.length;
elm.selectionEnd = elm.value.length;
} else if(elm.createTextRange != void 0) {
elm.focus();
var range = elm.createTextRange();
range.collapse(false);
range.select();
}
}
</syntaxhighlight>
|-
|resizable_chat()
|Makes the chat resize on grabbing of corners or edges.
|
|<syntaxhighlight lang="js" line="1" start="395">
function resizable_chat() {
var state = 0;
var isDown = false;
var downX = 0;
var downY = 0;
var elmX = 0;
var elmY = 0;
var chatWidth = 0;
var chatHeight = 0;
chat_window.addEventListener("mousemove", function(e) {
if(isDown) return;
var posX = e.pageX - chat_window.offsetLeft;
var posY = e.pageY - chat_window.offsetTop;
var top = (posY) <= 4;
var left = (posX) <= 3;
var right = (chat_window.offsetWidth - posX) <= 4;
var bottom = (chat_window.offsetHeight - posY) <= 5;
var cursor = "";
if(left || right) cursor = "ew-resize";
if(top || bottom) cursor = "ns-resize";
if((top && left) || (right && bottom)) cursor = "nwse-resize";
if((bottom && left) || (top && right)) cursor = "nesw-resize";
chat_window.style.cursor = cursor;
state = bottom << 3 | right << 2 | left << 1 | top;
});
chat_window.addEventListener("mousedown", function(e) {
downX = e.pageX;
downY = e.pageY;
if(state) {
// subtract 2 for the borders
chatWidth = chat_window.offsetWidth - 2;
chatHeight = chat_window.offsetHeight - 2;
elmX = chat_window.offsetLeft;
elmY = chat_window.offsetTop;
isDown = true;
chatResizing = true;
}
});
document.addEventListener("mouseup", function() {
isDown = false;
chatResizing = false;
});
document.addEventListener("mousemove", function(e) {
if(!isDown) return;
var offX = e.pageX - downX;
var offY = e.pageY - downY;
var resize_bottom = state >> 3 & 1;
var resize_right = state >> 2 & 1;
var resize_left = state >> 1 & 1;
var resize_top = state & 1;
var width_delta = 0;
var height_delta = 0;
var abs_top = chat_window.offsetTop;
var abs_left = chat_window.offsetLeft;
var snap_bottom = chat_window.style.bottom == "0px";
var snap_right = chat_window.style.right == "0px";
if(resize_top) {
height_delta = -offY;
} else if(resize_bottom) {
height_delta = offY;
}
if(resize_left) {
width_delta = -offX;
} else if(resize_right) {
width_delta = offX;
}
var res = resizeChat(chatWidth + width_delta, chatHeight + height_delta);
if(resize_top && !snap_bottom) {
chat_window.style.top = (elmY + (chatHeight - res[1])) + "px";
}
if(resize_bottom && snap_bottom) {
chat_window.style.bottom = "";
chat_window.style.top = abs_top + "px";
}
if(resize_right && snap_right) {
chat_window.style.right = "";
chat_window.style.left = abs_left + "px";
}
if(resize_left && !snap_right) {
chat_window.style.left = (elmX + (chatWidth - res[0])) + "px";
}
});
}
</syntaxhighlight>
|}
=== Variables ===
== permissions.js ==
=== Variables ===
{| class="wikitable"
|+
!Name
!Description
!Related code
|-
|PERM
|Defines permission numbers for easier use instead of writing "Admin"
|<syntaxhighlight lang="js" line="1" start="1">
var PERM = {
ADMIN: 2,
MEMBERS: 1,
PUBLIC: 0
};
</syntaxhighlight>
|}
==== Permissions ====
Since <code>Permissions</code> is a very long dictionary variable, this table is divided into specific definitions in it.
{| class="wikitable"
|+
!Name
!Description
!Related definition
|-
|can_admin
|Checks if user is an admin.
|<syntaxhighlight lang="js" line="1" start="7">
can_admin: function(user) {
return user.is_owner;
},
</syntaxhighlight>
|-
|can_coordlink
|Checks if user can create coordinate links in the world they're in.
|<syntaxhighlight lang="js" line="1" start="10">
can_coordlink: function(user, world) {
return Permissions.user_matches_perm(user, world, world.feature_coord_link);
},
</syntaxhighlight>
|-
|can_edit_tile
|Checks if user can write in a tile / character (protections).
|<syntaxhighlight lang="js" line="1" start="13">
can_edit_tile: function(user, world, tile, charX, charY) {
if(!tile) {
throw new Error("Can't check perms on un-initted tile");
}
if(!Permissions.can_read(user, world)) {
return false;
}
var targetWritability;
if(tile.char) {
targetWritability = tile.char[charY * tileC + charX];
if(targetWritability == null) targetWritability = tile.writability; // inherit from tile
if(targetWritability == null) targetWritability = world.writability; // inherit from world
} else {
targetWritability = tile.writability;
if(targetWritability == null) targetWritability = world.writability;
}
return Permissions.user_matches_perm(user, world, targetWritability);
},
</syntaxhighlight>
|-
|can_go_to_coord
|Checks if user can teleport.
|<syntaxhighlight lang="js" line="1" start="31">
can_go_to_coord: function(user, world) {
return Permissions.user_matches_perm(user, world, world.feature_go_to_coord);
},
</syntaxhighlight>
|-
|can_paste
|Checks if user can paste.
|<syntaxhighlight lang="js" line="1" start="34">
can_paste: function(user, world) {
return Permissions.user_matches_perm(user, world, world.feature_paste);
},
</syntaxhighlight>
|-
|can_copy
|Checks if user can copy.
|<syntaxhighlight lang="js" line="1" start="37">
can_copy: function(user, world) {
if(user.is_owner || user.is_member) return true;
return !world.no_copy;
},
</syntaxhighlight>
|-
|can_protect_tiles
|Checks if user can protect tiles.
|<syntaxhighlight lang="js" line="1" start="41">
can_protect_tiles: function(user, world) {
if(user.is_owner) return true;
return world.feature_membertiles_addremove && user.is_member;
},
</syntaxhighlight>
|-
|can_erase
|Checks if user can use the built-in eraser.
|<syntaxhighlight lang="js" line="1" start="45">
can_erase: function(user, world) {
if(user.is_owner) return true;
return Permissions.user_matches_perm(user, world, world.quick_erase);
},
</syntaxhighlight>
|-
|can_read
|Checks if user can view the world.
|<syntaxhighlight lang="js" line="1" start="49">
can_read: function(user, world) {
return Permissions.user_matches_perm(user, world, world.readability);
},
</syntaxhighlight>
|-
|can_urllink
|Checks if user can create links leading to other URL's.
|<syntaxhighlight lang="js" line="1" start="52">
can_urllink: function(user, world) {
return Permissions.user_matches_perm(user, world, world.feature_url_link);
},
</syntaxhighlight>
|-
|can_write
|Checks if user can write on the world.
|<syntaxhighlight lang="js" line="1" start="55">
can_write: function(user, world) {
if(!Permissions.can_read(user, world)) {
return false;
}
return Permissions.user_matches_perm(user, world, world.writability);
},
</syntaxhighlight>
|-
|can_chat
|Checks if user can chat.
|<syntaxhighlight lang="js" line="1" start="61">
can_chat: function(user, world) {
return Permissions.user_matches_perm(user, world, world.chat_permission);
},
</syntaxhighlight>
|-
|can_show_cursor
|Checks if showing cursors is enabled for a user.
|<syntaxhighlight lang="js" line="1" start="64">
can_show_cursor: function(user, world) {
return Permissions.user_matches_perm(user, world, world.show_cursor);
},
</syntaxhighlight>
|-
|can_color_text
|Checks if user can change their text colour.
|<syntaxhighlight lang="js" line="1" start="67">
can_color_text: function(user, world) {
return Permissions.user_matches_perm(user, world, world.color_text);
},
</syntaxhighlight>
|-
|can_color_cell
|Checks if user can change their cell colour.
|<syntaxhighlight lang="js" line="1" start="70">
can_color_cell: function(user, world) {
return Permissions.user_matches_perm(user, world, world.color_cell);
},
</syntaxhighlight>
|-
|user_matches_perm
|Gets users permissions.
|<syntaxhighlight lang="js" line="1" start="73">
user_matches_perm: function(user, world, perm) {
if(perm == -1) { // no one
return false;
}
if(perm == PERM.PUBLIC) { // anyone
return true;
}
if(user.is_owner) {
return true;
}
if(perm == PERM.ADMIN) {
return false;
}
if(perm == PERM.MEMBERS && user.is_member) {
return true;
}
return false;
}
};
</syntaxhighlight>
</syntaxhighlight>
|}
|}
[[Category:Articles nominated by Guest-1052]]
[[Category:Documentation]]