Unify TODO comments

main
Isaiah Odhner 2020-01-05 17:27:51 -05:00
parent 97cd1aeea1
commit 31edf30064
33 changed files with 144 additions and 144 deletions

View File

@ -49,31 +49,31 @@ context('visual tests', () => {
});
it('flip and rotate window', () => {
// TODO: make menus more testable, with IDs
// @TODO: make menus more testable, with IDs
cy.get('.menus > .menu-container:nth-child(4) > .menu-button > .menu-hotkey').click();
cy.get('.menus > .menu-container:nth-child(4) > .menu-popup > table > tr:nth-child(1)').click();
cy.get('.window:visible').matchImageSnapshot();
});
it('stretch and skew window', () => {
// TODO: make menus more testable, with IDs
// @TODO: make menus more testable, with IDs
cy.get('.menus > .menu-container:nth-child(4) > .menu-button > .menu-hotkey').click();
cy.get('.menus > .menu-container:nth-child(4) > .menu-popup > table > tr:nth-child(2)').click();
// TODO: wait for images to load and include images?
// @TODO: wait for images to load and include images?
cy.get('.window:visible').matchImageSnapshot({ blackout: ["img"] });
});
it('help window', () => {
// TODO: make menus more testable, with IDs
// @TODO: make menus more testable, with IDs
cy.get('.menus > .menu-container:nth-child(6) > .menu-button > .menu-hotkey').click();
cy.get('.menus > .menu-container:nth-child(6) > .menu-popup > table > tr:nth-child(1)').click();
cy.get('.window:visible .folder', {timeout: 10000}); // wait for sidebar contents to load
// TODO: wait for iframe to load
// @TODO: wait for iframe to load
cy.get('.window:visible').matchImageSnapshot({ blackout: ["iframe"] });
});
it('about window', () => {
// TODO: make menus more testable, with IDs
// @TODO: make menus more testable, with IDs
cy.get('.menus > .menu-container:nth-child(6) > .menu-button > .menu-hotkey').click();
cy.get('.menus > .menu-container:nth-child(6) > .menu-popup > table > tr:nth-child(3)').click();
cy.get('.window:visible').matchImageSnapshot({ blackout: ["img"] });

View File

@ -12,9 +12,9 @@
<li>Click <b>Black and white</b>.</li>
</ol>
<!--
As of writing, there's no conversion to monochrome.
The black and white mode just works with color in the document.
TODO: add *optional* conversion to monochrome, and update this help accordingly
There's now a conversion to monochrome
(altho the black and white mode allows color in the document.)
@TODO: Update this help accordingly
-->
<!--
<p><b>Note</b></p>

View File

@ -16,7 +16,7 @@
</ol>
<p><b>Notes</b></p>
<ul>
<!-- TODO: maybe emulate the color picker dialog and make this note unecessary: -->
<!-- @TODO: maybe emulate the color picker dialog and make this note unecessary: -->
<li>
These instructions are very operating system specific and you may get a completely different color picker.
On some systems the color picker may be utterly useless, and give you less color options than the default palette.

View File

@ -30,7 +30,7 @@
<p><b>Notes</b></p>
<ul>
<li>JS Paint can't directly set your wallpaper, but it can generate a tiled image the size of your desktop.</li>
<!-- TODO: make this note unnecessary? -->
<!-- @TODO: make this note unnecessary? -->
<li>The <b>Set As Wallpaper (Centered)</b> option doesn't currently use your desktop size, it just saves a copy of the image.
You need to make sure in your system settings to choose to center the image.</li>
</ul>

View File

@ -5,7 +5,7 @@ function E(t){
return document.createElement(t);
}
// TODO: make menus not take focus so we can support copy/pasting text in the text tool textarea from the menus
// @TODO: make menus not take focus so we can support copy/pasting text in the text tool textarea from the menus
const MENU_DIVIDER = "MENU_DIVIDER";
@ -38,7 +38,7 @@ function $MenuBar(menus){
}
};
// TODO: API for context menus (i.e. floating menu popups)
// @TODO: API for context menus (i.e. floating menu popups)
function $MenuPopup(menu_items){
const $menu_popup = $(E("div")).addClass("menu-popup");
const $menu_popup_table = $(E("table")).addClass("menu-popup-table").appendTo($menu_popup);

View File

@ -85,9 +85,9 @@
"lint-cat": "concat-glob-cli --files \"src/**/!(electron*).js\" --output concatenated-source.js && eslint --rule \"no-undef: error\" --rule \"no-unused-vars: error\" concatenated-source.js",
"lint-cat:NOTE": "Disable the eslint comment that disables ThisExpression to use this.",
"dev": "live-server --ignorePattern=\"(node_modules|cypress|out)[/\\\\\\\\]|package\\.json|cypress\\.json\"",
"dev:NOTE": "XXX: the octuple backlash ends up meaning a single backslash on Linux, two backslashes on Windows. In this case it's fine because it's in a regexp character class so the extra is redundant and doesn't cause an error.",
"dev:NOTE": "@XXX: the octuple backlash ends up meaning a single backslash on Linux, two backslashes on Windows. In this case it's fine because it's in a regexp character class so the extra is redundant and doesn't cause an error.",
"test:start-server": "live-server --port=11822 --no-browser --ignorePattern=\"(node_modules|cypress|out)[/\\\\\\\\]|package\\.json|cypress\\.json\"",
"test:start-server:NOTE": "XXX: the octuple backlash ends up meaning a single backslash on Linux, two backslashes on Windows. In this case it's fine because it's in a regexp character class so the extra is redundant and doesn't cause an error.",
"test:start-server:NOTE": "@XXX: the octuple backlash ends up meaning a single backslash on Linux, two backslashes on Windows. In this case it's fine because it's in a regexp character class so the extra is redundant and doesn't cause an error.",
"cy:open": "cypress open",
"cy:run": "cypress run",
"cy:accept": "cypress run --env updateSnapshots=true",

View File

@ -101,7 +101,7 @@ function $ColorBox(vertical){
$i.val(color_to_hex(color));
$b.on("pointerdown", e => {
// TODO: how should the ternary color, and selection cropping, work on macOS?
// @TODO: how should the ternary color, and selection cropping, work on macOS?
ctrl = e.ctrlKey;
button = e.button;
if(button === 0){
@ -160,7 +160,7 @@ function $ColorBox(vertical){
// Edit the last color cell that's been selected as the foreground color.
create_and_trigger_input({type: "color"}, input => {
// window.console && console.log(input, input.value);
// FIXME
// @FIXME
$last_fg_color_button.trigger({type: "pointerdown", ctrlKey: false, button: 0});
$last_fg_color_button.find("input").val(input.value).triggerHandler("change");
})

View File

@ -89,7 +89,7 @@ function $Component(name, orientation, $el){
let iid;
if($("body").hasClass("eye-gaze-mode")){
// TODO: don't use an interval for this!
// @TODO: don't use an interval for this!
iid = setInterval(()=> {
const scale = 3;
$c.css({

View File

@ -59,7 +59,7 @@ function $Handles($container, getRect, options){
const rect = getRect();
const m = to_canvas_coords(event);
// TODO: decide between Math.floor/Math.ceil/Math.round for these values
// @TODO: decide between Math.floor/Math.ceil/Math.round for these values
if(x_axis === "right"){
delta_x = 0;
width = ~~(m.x - rect.left);

View File

@ -21,9 +21,9 @@ function $ToolWindow($component){
e.preventDefault();
});
// TODO: prevent selection *outside* of the window *via* the window
// @TODO: prevent selection *outside* of the window *via* the window
// TODO: keep track of last focused control in the window, and focus it when clicking on / focusing the window
// @TODO: keep track of last focused control in the window, and focus it when clicking on / focusing the window
$w.css({
position: "absolute",
@ -81,9 +81,9 @@ function $ToolWindow($component){
break;
case 9: { // Tab
// TODO: handle shift+tab as well (note: early return at top of function)
// @TODO: handle shift+tab as well (note: early return at top of function)
// wrap around when tabbing through controls in a window
// TODO: other element types? also [tabIndex]
// @TODO: other element types? also [tabIndex]
const $controls = $w.$content.find("input, textarea, select, button, a");
const focused_control_index = $controls.index($focused);
if(focused_control_index === $controls.length - 1){

View File

@ -23,7 +23,7 @@ class OnCanvasSelection extends OnCanvasObject {
}
position() {
super.position(true);
update_helper_layer(); // TODO: under-grid specific helper layer?
update_helper_layer(); // @TODO: under-grid specific helper layer?
}
instantiate(img) {
this.$el.css({
@ -39,7 +39,7 @@ class OnCanvasSelection extends OnCanvasObject {
// (width vs naturalWidth?)
// and at least apply_image_transformation needs it to be a canvas now (and the property name says canvas anyways)
this.source_canvas = make_canvas(img);
// TODO: is this width/height code needed? probably not! wouldn't it clear the canvas anyways?
// @TODO: is this width/height code needed? probably not! wouldn't it clear the canvas anyways?
// but maybe we should assert in some way that the widths are the same, or resize the selection?
if (this.source_canvas.width !== this.width) {
this.source_canvas.width = this.width;
@ -114,7 +114,7 @@ class OnCanvasSelection extends OnCanvasObject {
this.draw();
});
}
// TODO: how should this work for macOS? where ctrl+click = secondary click?
// @TODO: how should this work for macOS? where ctrl+click = secondary click?
else if (e.ctrlKey) {
// Stamp selection
undoable({
@ -143,7 +143,7 @@ class OnCanvasSelection extends OnCanvasObject {
// and should end up as the cut out image data for the selection
// canvasImageData is initially the portion of image data on the canvas,
// and should end up as... the portion of image data on the canvas that it should end up as.
// TODO: could simplify by making the later (shared) condition just if(colored_cutout){}
// @TODO: could simplify by making the later (shared) condition just if(colored_cutout){}
// but might change how it works anyways so whatever
// if(!transparency){ // now if !transparency or if tool_transparent_mode
// this is mainly in order to support patterns as the background color
@ -180,7 +180,7 @@ class OnCanvasSelection extends OnCanvasObject {
// (and it would be complicated to make it update the canvas when switching tool options (as opposed to just the selection))
// I'm having it use the tool_transparent_mode option here, so you could at least choose beforehand
// (and this might actually give you more options, although it could be confusingly inconsistent)
// FIXME: yeah, this is confusing; if you have both transparency modes on and you try to clear an area to transparency, it doesn't work
// @FIXME: yeah, this is confusing; if you have both transparency modes on and you try to clear an area to transparency, it doesn't work
// and there's no indication that you should try the other selection transparency mode,
// and even if you do, if you do it after creating a selection, it still won't work,
// because you will have already *not cut out* the selection from the canvas
@ -202,7 +202,7 @@ class OnCanvasSelection extends OnCanvasObject {
for (let i = 0; i < cutoutImageData.data.length; i += 4) {
let in_cutout = sourceImageData.data[i + 3] > 0;
if (tool_transparent_mode) {
// FIXME: work with transparent selected background color
// @FIXME: work with transparent selected background color
// (support treating partially transparent background colors as transparency)
if (sourceImageData.data[i + 0] === background_color_rgba[0] &&
sourceImageData.data[i + 1] === background_color_rgba[1] &&
@ -228,7 +228,7 @@ class OnCanvasSelection extends OnCanvasObject {
update_helper_layer();
}
// TODO: should Image > Invert apply to this.source_canvas or to this.canvas (replacing this.source_canvas with the result)?
// @TODO: should Image > Invert apply to this.source_canvas or to this.canvas (replacing this.source_canvas with the result)?
replace_source_canvas(new_source_canvas) {
this.source_canvas = new_source_canvas;
const new_canvas = make_canvas(new_source_canvas);
@ -274,6 +274,6 @@ class OnCanvasSelection extends OnCanvasObject {
destroy() {
super.destroy();
$G.off("option-changed", this._on_option_changed);
update_helper_layer(); // TODO: under-grid specific helper layer?
update_helper_layer(); // @TODO: under-grid specific helper layer?
}
}

View File

@ -82,7 +82,7 @@ class OnCanvasTextBox extends OnCanvasObject {
this.canvas.width = this.width;
this.canvas.height = this.height;
this.canvas.ctx.drawImage(img, 0, 0);
update_helper_layer(); // TODO: under-grid specific helper layer?
update_helper_layer(); // @TODO: under-grid specific helper layer?
};
img.onerror = (e)=> {
window.console && console.log("Failed to load image", e);
@ -125,7 +125,7 @@ class OnCanvasTextBox extends OnCanvasObject {
this.y = Math.max(Math.min(m.y - moy, canvas.height), -this.height);
this.position();
if (e.shiftKey) {
// TODO: maybe re-enable but handle undoables well
// @TODO: maybe re-enable but handle undoables well
// this.draw();
}
};
@ -185,7 +185,7 @@ class OnCanvasTextBox extends OnCanvasObject {
}
position() {
super.position(true);
update_helper_layer(); // TODO: under-grid specific helper layer?
update_helper_layer(); // @TODO: under-grid specific helper layer?
}
destroy() {
super.destroy();
@ -197,6 +197,6 @@ class OnCanvasTextBox extends OnCanvasObject {
this.$editor.off("input", this._on_input);
this.$editor.off("scroll", this._on_scroll);
$(window).off("resize", this._on_window_resize);
update_helper_layer(); // TODO: under-grid specific helper layer?
update_helper_layer(); // @TODO: under-grid specific helper layer?
}
}

View File

@ -180,7 +180,7 @@ $news_indicator.on("click auxclick", (event)=> {
event.preventDefault();
show_news();
});
// TODO: use localstorage to show until clicked, if available
// @TODO: use localstorage to show until clicked, if available
// and show for a longer period of time after the update, if available
if (Date.now() < Date.parse("Jan 5 2020 23:42:42 GMT-0500")) {
$status_area.append($news_indicator);
@ -298,7 +298,7 @@ $G.on("keydown", e => {
e.preventDefault();
return;
}
// TODO: return if menus/menubar focused or focus in dialog window
// @TODO: return if menus/menubar focused or focus in dialog window
// or maybe there's a better way to do this that works more generally
// maybe it should only handle the event if document.activeElement is the body or html element?
// (or $app could have a tabIndex and no focus style and be focused under various conditions,
@ -310,7 +310,7 @@ $G.on("keydown", e => {
return;
}
// TODO: preventDefault in all cases where the event is handled
// @TODO: preventDefault in all cases where the event is handled
// also, ideally check that modifiers *aren't* pressed
// probably best to use a library at this point!
@ -522,7 +522,7 @@ reset_colors();
reset_canvas_and_history(); // (with newly reset colors)
set_magnification(default_magnification);
// this is synchronous for now, but TODO: handle possibility of loading a document before callback
// this is synchronous for now, but @TODO: handle possibility of loading a document before callback
// when switching to asynchronous storage, e.g. with localforage
storage.get({
width: default_canvas_width,
@ -1247,7 +1247,7 @@ $canvas_area.on("pointerdown", (event)=> {
// prevent multitouch panning in case of dragging across iframe boundary with a mouse/pen
// Note: there can be multiple active primary pointers, one per pointer type
!(pointer.isPrimary && (pointer.pointerType === "mouse" || pointer.pointerType === "pen"))
// TODO: handle case of dragging across iframe boundary with touch
// @TODO: handle case of dragging across iframe boundary with touch
)) {
pointers.push({
pointerId: event.pointerId,

View File

@ -10,7 +10,7 @@ const fs = require("fs");
const path = require("path");
const argv = require("electron").remote.process.argv;
// TODO: let user apply this setting somewhere in the UI
// @TODO: let user apply this setting somewhere in the UI
// (and ideally revert it)
// (Note: it would be better to use REG.EXE to apply the change, rather than a .reg file)
// This registry modification changes the right click > Edit option for images in Windows Explorer
@ -106,18 +106,18 @@ function blob_to_buffer(blob, callback) {
return file_reader;
}
// TODO: window.platform.saveCanvasAs etc. or platformIntegration or system or something
// @TODO: window.platform.saveCanvasAs etc. or platformIntegration or system or something
window.systemSaveCanvasAs = (canvas, suggestedFileName, savedCallback) => {
const getExtension = filePathOrName => {
const splitByDots = filePathOrName.split(/\./g);
return splitByDots[splitByDots.length - 1].toLowerCase();
};
// TODO: default to existing extension, except it would be awkward to rearrange the list...
// @TODO: default to existing extension, except it would be awkward to rearrange the list...
// const suggestedExtension = getExtension(suggestedFileName);
const filters = [
// top one is considered default by electron
{name: "PNG", extensions: ["png"]},
// TODO: enable more formats
// @TODO: enable more formats
// {name: "Monochrome Bitmap", extensions: ["bmp", "dib"]},
// {name: "16 Color Bitmap", extensions: ["bmp", "dib"]},
// {name: "256 Color Bitmap", extensions: ["bmp", "dib"]},
@ -128,8 +128,8 @@ window.systemSaveCanvasAs = (canvas, suggestedFileName, savedCallback) => {
// {name: "PNG", extensions: ["png"]},
{name: "WebP", extensions: ["webp"]},
];
// TODO: pass BrowserWindow to make dialog modal?
// TODO: should suggestedFileName be sanitized in some way?
// @TODO: pass BrowserWindow to make dialog modal?
// @TODO: should suggestedFileName be sanitized in some way?
dialog.showSaveDialog({
defaultPath: suggestedFileName,
filters,
@ -139,7 +139,7 @@ window.systemSaveCanvasAs = (canvas, suggestedFileName, savedCallback) => {
}
const extension = getExtension(filePath);
if(!extension){
// TODO: Linux/Unix?? you're not supposed to need file extensions
// @TODO: Linux/Unix?? you're not supposed to need file extensions
return show_error_message("Missing file extension - try adding .png to the file name");
}
const formatNameMatched = ((filters.find(({extensions}) => extensions.includes(extension))) || {}).name;
@ -158,7 +158,7 @@ window.systemSetAsWallpaperCentered = c => {
const fs = require("fs");
const wallpaper = require("wallpaper");
// TODO: implement centered option for Windows and Linux in https://www.npmjs.com/package/wallpaper
// @TODO: implement centered option for Windows and Linux in https://www.npmjs.com/package/wallpaper
// currently it's only supported on macOS
let wallpaperCanvas;
if(process.platform === "darwin"){

View File

@ -36,7 +36,7 @@ const createWindow = () => {
},
});
// TODO: maybe use the native menu for the "Modern" theme
// @TODO: maybe use the native menu for the "Modern" theme
mainWindow.setMenu(null);
// and load the index.html of the app.

View File

@ -8,8 +8,8 @@ extra_tools = [{
rendered_size: 0,
rendered_shape: "",
paint(ctx, x, y) {
// XXX: copy pasted all this brush caching/rendering code!
// TODO: DRY!
// @XXX: copy pasted all this brush caching/rendering code!
// @TODO: DRY!
const csz = get_brush_canvas_size(brush_size, brush_shape);
if(
this.rendered_shape !== brush_shape ||
@ -64,8 +64,8 @@ extra_tools = [{
this.velocity.y = 0;
},
paint(ctx, x, y) {
// XXX: copy pasted all this brush caching/rendering code!
// TODO: DRY!
// @XXX: copy pasted all this brush caching/rendering code!
// @TODO: DRY!
const csz = get_brush_canvas_size(brush_size, brush_shape);
if(
this.rendered_shape !== brush_shape ||

View File

@ -179,7 +179,7 @@ function show_custom_zoom_window() {
const $w = new $FormToolWindow("Custom Zoom");
$custom_zoom_window = $w;
// TODO: show Current zoom: blah% ?
// @TODO: show Current zoom: blah% ?
const $fieldset = $(E("fieldset")).appendTo($w.$main);
$fieldset.append("<legend>Zoom to</legend>");
$fieldset.append("<label><input type='radio' name='custom-zoom-radio' value='1'/>100%</label>");
@ -352,9 +352,9 @@ function create_and_trigger_input(attrs, callback){
return $input;
}
// TODO: rename these functions to lowercase (and maybe say "files" in this case)
// @TODO: rename these functions to lowercase (and maybe say "files" in this case)
function get_FileList_from_file_select_dialog(callback){
// TODO: specify mime types?
// @TODO: specify mime types?
create_and_trigger_input({type: "file"}, input => {
callback(input.files);
});
@ -362,7 +362,7 @@ function get_FileList_from_file_select_dialog(callback){
function open_from_Image(img, callback, canceled){
are_you_sure(() => {
// TODO: shouldn't open_from_* start a new session?
// @TODO: shouldn't open_from_* start a new session?
deselect();
cancel();
@ -379,7 +379,7 @@ function open_from_Image(img, callback, canceled){
current_history_node.name = "Load Document";
current_history_node.image_data = ctx.getImageData(0, 0, canvas.width, canvas.height);
current_history_node.icon = null; // TODO
current_history_node.icon = null; // @TODO
$G.triggerHandler("session-update"); // autosave
$G.triggerHandler("history-update"); // update history view
@ -407,7 +407,7 @@ function get_URIs(text) {
return uris;
}
function load_image_from_URI(uri, callback){
// TODO: if URI is not blob: or data:, show dialog with progress bar and this string from mspaint.exe: "Downloading picture"
// @TODO: if URI is not blob: or data:, show dialog with progress bar and this string from mspaint.exe: "Downloading picture"
fetch(uri)
.then(response => response.blob()).then(blob => {
const img = new Image();
@ -503,7 +503,7 @@ function file_new(){
});
}
// TODO: factor out open_select/choose_file_dialog or get_file_from_file_select_dialog or whatever
// @TODO: factor out open_select/choose_file_dialog or get_file_from_file_select_dialog or whatever
// all these open_from_* things are done backwards, basically
// there's this little thing called Inversion of Control...
// also paste_from_file_select_dialog
@ -521,13 +521,13 @@ function file_load_from_url(){
const $w = new $FormToolWindow().addClass("dialogue-window");
$file_load_from_url_window = $w;
$w.title("Load from URL");
// TODO: URL validation (input has to be in a form (and we don't want the form to submit))
// @TODO: URL validation (input has to be in a form (and we don't want the form to submit))
$w.$main.html("<label>URL: <input type='url' required value='' class='url-input'/></label>");
const $input = $w.$main.find(".url-input");
$w.$Button("Load", () => {
const uris = get_URIs($input.val());
if (uris.length > 0) {
// TODO: retry loading if same URL entered
// @TODO: retry loading if same URL entered
// actually, make it change the hash only after loading successfully
// (but still load from the hash when necessary)
// make sure it doesn't overwrite the old session before switching
@ -547,12 +547,12 @@ function file_load_from_url(){
function file_save(){
deselect();
if(file_name.match(/\.svg$/)){
//TODO: only affect suggested name in save dialog, don't change file_name
// @TODO: only affect suggested name in save dialog, don't change file_name
file_name = `${file_name.replace(/\.svg$/, "")}.png`;
return file_save_as();
}
if(document_file_path){
// TODO: save as JPEG by default if the previously opened/saved file was a JPEG?
// @TODO: save as JPEG by default if the previously opened/saved file was a JPEG?
return save_to_file_path(document_file_path, "PNG", (saved_file_path, saved_file_name) => {
saved = true;
document_file_path = saved_file_path;
@ -630,7 +630,7 @@ function show_error_message(message, error){
}
}
// TODO: close are_you_sure windows and these Error windows when switching sessions
// @TODO: close are_you_sure windows and these Error windows when switching sessions
// because it can get pretty confusing
function show_resource_load_error_message(){
// NOTE: apparently distinguishing cross-origin errors is disallowed
@ -682,7 +682,7 @@ function show_about_paint(){
$("#outdated").attr("hidden", "hidden");
$about_paint_window.center();
$about_paint_window.center(); // XXX - but it helps tho
$about_paint_window.center(); // @XXX - but it helps tho
$("#refresh-to-update").on("click", (event)=> {
event.preventDefault();
@ -720,7 +720,7 @@ function show_about_paint(){
);
}
// TODO: visibly mark entries that overlap
// @TODO: visibly mark entries that overlap
entries_newer_than_this_version =
$latest_entries.get().filter((el_from_latest)=>
!entries_contains_update($this_version_entries, el_from_latest.id)
@ -785,11 +785,11 @@ function show_news(){
$news_window.$content.append($latest_news.removeAttr("hidden"));
$news_window.center();
$news_window.center(); // XXX - but it helps tho
$news_window.center(); // @XXX - but it helps tho
}
// TODO: DRY between these functions and open_from_* functions further?
// @TODO: DRY between these functions and open_from_* functions further?
// function paste_image_from_URI(uri, callback){
// load_image_from_URI(uri, (err, img)=> {
@ -802,7 +802,7 @@ function paste_image_from_file(file){
const blob_url = URL.createObjectURL(file);
// paste_image_from_URI(blob_url);
load_image_from_URI(blob_url, (err, img) => {
// TODO: this shouldn't really have the CORS error message, if it's from a blob URI
// @TODO: this shouldn't really have the CORS error message, if it's from a blob URI
if(err){ return show_resource_load_error_message(); }
paste(img);
URL.revokeObjectURL(blob_url);
@ -981,7 +981,7 @@ function go_to_history_node(target_history_node, canceling) {
if (selection) {
selection.destroy();
}
// TODO maybe: could store whether a selection is from Free-Form Select
// @TODO maybe: could store whether a selection is from Free-Form Select
// so it selects Free-Form Select when you jump to e.g. Move Selection
// (or could traverse history to figure it out)
if (target_history_node.name === "Free-Form Select") {
@ -1279,7 +1279,7 @@ function meld_selection_into_canvas(going_to_history_node) {
undoable({
name: "Deselect",
icon: get_icon_for_tool(get_tool_by_name("Select")),
use_loose_canvas_changes: true, // HACK; TODO: make OnCanvasSelection not change the canvas outside undoable, same rules as tools
use_loose_canvas_changes: true, // HACK; @TODO: make OnCanvasSelection not change the canvas outside undoable, same rules as tools
}, ()=> { });
}
}
@ -1320,7 +1320,7 @@ function delete_selection(meta={}){
undoable({
name: meta.name || "Delete",
icon: meta.icon || get_help_folder_icon("p_delete.png"),
// soft: TODO: conditionally soft?,
// soft: @TODO: conditionally soft?,
}, ()=> {
selection.destroy();
selection = null;
@ -2037,14 +2037,14 @@ function image_stretch_and_skew(){
$w.center();
}
// TODO: establish a better pattern for this (platform-specific functions, with browser-generic fallbacks)
// @TODO: establish a better pattern for this (platform-specific functions, with browser-generic fallbacks)
// Note: we can't just poke in a different save_canvas_as function in electron-injected.js because electron-injected.js is loaded first
function save_canvas_as(canvas, fileName, savedCallbackUnreliable){
if(window.systemSaveCanvasAs){
return systemSaveCanvasAs(canvas, fileName, savedCallbackUnreliable);
}
// TODO: file name + type dialog
// @TODO: file name + type dialog
canvas.toBlob(blob => {
sanity_check_blob(blob, () => {
const file_saver = saveAs(blob, `${file_name.replace(/\.(bmp|dib|a?png|gif|jpe?g|jpe|jfif|tiff?|webp|raw)$/, "")}.png`);

View File

@ -100,7 +100,7 @@ function open_help_viewer(options){
forward_length -= 1;
back_length += 1;
}, ()=> forward_length > 0);
add_toolbar_button("Options", 3, ()=> {}, ()=> false); // TODO: hotkey and underline on O
add_toolbar_button("Options", 3, ()=> {}, ()=> false); // @TODO: hotkey and underline on O
add_toolbar_button("Web Help", 4, ()=> {
iframe.src = "help/online_support.htm";
});
@ -111,7 +111,7 @@ function open_help_viewer(options){
const $resizer = $(E("div")).addClass("resizer");
const $contents = $(E("ul")).addClass("contents inset-deep");
// TODO: fix race conditions
// @TODO: fix race conditions
$iframe.on("load", ()=> {
if (!ignore_one_load) {
back_length += 1;
@ -369,7 +369,7 @@ function $Iframe(options){
iframe.contentWindow.close = function(){
iframe.$window && iframe.$window.close();
};
// TODO: hook into saveAs (a la FileSaver.js) and another function for opening files
// @TODO: hook into saveAs (a la FileSaver.js) and another function for opening files
// iframe.contentWindow.saveAs = function(){
// saveAsDialog();
// };
@ -395,7 +395,7 @@ function $Iframe(options){
// var $iframe = $win.$iframe = $Iframe({src: options.src});
// $win.$content.append($iframe);
// var iframe = $win.iframe = $iframe[0];
// // TODO: should I instead of having iframe.$window, have a get$Window type of dealio?
// // @TODO: should I instead of having iframe.$window, have a get$Window type of dealio?
// // where all is $window needed?
// // I know it's used from within the iframe contents as frameElement.$window
// iframe.$window = $win;
@ -428,7 +428,7 @@ function $Iframe(options){
// flexDirection: "column",
// });
// // TODO: cascade windows
// // @TODO: cascade windows
// $win.center();
// $win.hide();

View File

@ -145,7 +145,7 @@ function make_canvas(width, height){
new_ctx.imageSmoothingEnabled = true;
};
// TODO: simplify the abstraction by defining setters for width/height
// @TODO: simplify the abstraction by defining setters for width/height
// that reset the image smoothing to disabled
// and make image smoothing a parameter to make_canvas

View File

@ -1,7 +1,7 @@
function get_brush_canvas_size(brush_size, brush_shape){
// brush_shape optional, only matters if it's circle
// TODO: does it actually still matter? the ellipse drawing code has changed
// @TODO: does it actually still matter? the ellipse drawing code has changed
// round to nearest even number in order for the canvas to be drawn centered at a point reasonably
return Math.ceil(brush_size * (brush_shape === "circle" ? 2.1 : 1) / 2) * 2;
@ -20,7 +20,7 @@ function render_brush(ctx, shape, size){
const bottom = Math.round(mid_y + size/2);
if(shape === "circle"){
// TODO: ideally _without_pattern_support
// @TODO: ideally _without_pattern_support
draw_ellipse(ctx, left, top, size, size, false, true);
// was useful for testing:
// ctx.fillStyle = "red";
@ -117,7 +117,7 @@ function draw_rounded_rectangle(ctx, x, y, width, height, radius_x, radius_y, st
}
// USAGE NOTE: must be called outside of any other usage of op_canvas (because of render_brush)
// TODO: protect against browser clearing canvases, invalidate cache
// @TODO: protect against browser clearing canvases, invalidate cache
const get_brush_canvas = memoize_synchronous_function((brush_shape, brush_size)=> {
const canvas_size = get_brush_canvas_size(brush_size, brush_shape);
@ -258,10 +258,10 @@ function brosandham_line(x1, y1, x2, y2, callback){
function draw_fill_without_pattern_support(ctx, start_x, start_y, fill_r, fill_g, fill_b, fill_a){
// TODO: split up processing in case it takes too long?
// @TODO: split up processing in case it takes too long?
// progress bar and abort button (outside of image-manipulation.js)
// or at least just free up the main thread every once in a while
// TODO: speed up with typed arrays? https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
// @TODO: speed up with typed arrays? https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
// could avoid endianness issues if only copying colors
// the jsperf only shows ~15% improvement
// maybe do something fancier like special-casing large chunks of single-color image
@ -797,7 +797,7 @@ function draw_bezier_curve_without_pattern_support(ctx, start_x, start_y, contro
let point_a = {x: start_x, y: start_y};
for(let t=0; t<1; t+=1/steps){
const point_b = compute_bezier(t, start_x, start_y, control_1_x, control_1_y, control_2_x, control_2_y, end_x, end_y);
// TODO: carry "error" from Bresenham line algorithm between iterations? and/or get a proper Bezier drawing algorithm
// @TODO: carry "error" from Bresenham line algorithm between iterations? and/or get a proper Bezier drawing algorithm
draw_line_without_pattern_support(ctx, point_a.x, point_a.y, point_b.x, point_b.y, stroke_size);
point_a = point_b;
}
@ -831,7 +831,7 @@ function draw_line(ctx, x1, y1, x2, y2, stroke_size){
let grid_pattern;
function draw_grid(ctx, scale) {
const pattern_size = Math.floor(scale); // TODO: try ceil too
const pattern_size = Math.floor(scale); // @TODO: try ceil too
if (!grid_pattern || grid_pattern.width !== pattern_size || grid_pattern.height !== pattern_size) {
const grid_pattern_canvas = make_canvas(pattern_size, pattern_size);
const dark_gray = "#808080";
@ -852,7 +852,7 @@ function draw_grid(ctx, scale) {
if (scale !== pattern_size) {
ctx.translate(-0.5, -0.75); // hand picked to look "good" at 110% in chrome
// might be better to just hide the grid in some more cases tho
// ...TODO: if I can get helper layer to be pixel aligned, I can probably remove this
// ...@TODO: if I can get helper layer to be pixel aligned, I can probably remove this
}
ctx.scale(scale / pattern_size, scale / pattern_size);
ctx.enable_image_smoothing();
@ -1161,7 +1161,7 @@ function draw_grid(ctx, scale) {
for (let i = 0; i < numPoints; i++) {
coords[i*2+0] = (points[i].x - x_min) / op_canvas_webgl.width * 2 - 1;
coords[i*2+1] = 1 - (points[i].y - y_min) / op_canvas_webgl.height * 2;
// TODO: investigate: does this cause resolution/information loss? can we change the coordinate system?
// @TODO: investigate: does this cause resolution/information loss? can we change the coordinate system?
}
if(fill){
@ -1225,7 +1225,7 @@ function draw_grid(ctx, scale) {
const width = x_max - x_min;
const height = y_max - y_min;
// TODO: maybe have the cutout only the width/height of the bounds
// @TODO: maybe have the cutout only the width/height of the bounds
// const cutout = make_canvas(width, height);
const cutout = make_canvas(canvas);
@ -1240,7 +1240,7 @@ function draw_grid(ctx, scale) {
return cutout_crop;
}
// TODO: maybe shouldn't be external...
// @TODO: maybe shouldn't be external...
window.draw_with_swatch = (ctx, x_min, y_min, x_max, y_max, swatch, callback) => {
const stroke_margin = ~~(stroke_size * 1.1);

View File

@ -10,7 +10,7 @@ function show_imgur_uploader(blob){
const $imgur_url_area = $(E("div")).appendTo($imgur_window.$main);
const $imgur_status = $(E("div")).appendTo($imgur_window.$main);
// TODO: maybe make this preview small but zoomable to full size?
// @TODO: maybe make this preview small but zoomable to full size?
// (starting small (max-width: 100%) and toggling to either scrollable or fullscreen)
// it should be clear that it's not going to upload a downsized version of your image
const $preview_image = $(E("img")).appendTo($preview_image_area);
@ -31,7 +31,7 @@ function show_imgur_uploader(blob){
$preview_image_area.remove();
$upload_button.remove();
$cancel_button.remove(); // TODO: allow canceling upload request
$cancel_button.remove(); // @TODO: allow canceling upload request
$imgur_window.width(300);
$imgur_window.center();
@ -54,7 +54,7 @@ function show_imgur_uploader(blob){
// show_error_message("Received an invalid JSON response from Imgur: ", responseJSON, but also error);
// $imgur_window.close();
// TODO: DRY, including with show_error_message
// @TODO: DRY, including with show_error_message
$(E("pre"))
.appendTo($imgur_status)
.text(responseJSON)
@ -117,7 +117,7 @@ function show_imgur_uploader(blob){
$imgur_url_area.append(
"<label>URL: </label>"
).append($imgur_url);
// TODO: a button to copy the URL to the clipboard
// @TODO: a button to copy the URL to the clipboard
// (also maybe put the URL in a readonly input)
const $delete_button = $imgur_window.$Button("Delete", () => {

View File

@ -94,8 +94,8 @@ function manage_storage(){
}
if (!localStorageAvailable) {
// TODO: DRY with similar message
// TODO: instructions for your browser; it's called Cookies in chrome/chromium at least, and "storage" gives NO results
// @TODO: DRY with similar message
// @TODO: instructions for your browser; it's called Cookies in chrome/chromium at least, and "storage" gives NO results
$message.html("<p>Please enable local storage in your browser's settings for local backup. It may be called Cookies, Storage, or Site Data.</p>");
} else if($table.find("tr").length == 0) {
$message.html("<p>All clear!</p>");

View File

@ -137,7 +137,7 @@ window.menus = {
item: "Cu&t",
shortcut: "Ctrl+X",
enabled: () =>
// TODO: support cutting text with this menu item as well (e.g. for the text tool)
// @TODO: support cutting text with this menu item as well (e.g. for the text tool)
!!selection,
action: ()=> {
edit_cut(true);
@ -148,7 +148,7 @@ window.menus = {
item: "&Copy",
shortcut: "Ctrl+C",
enabled: () =>
// TODO: support copying text with this menu item as well (e.g. for the text tool)
// @TODO: support copying text with this menu item as well (e.g. for the text tool)
!!selection,
action: ()=> {
edit_copy(true);
@ -159,7 +159,7 @@ window.menus = {
item: "&Paste",
shortcut: "Ctrl+V",
enabled: () =>
// TODO: disable if nothing in clipboard or wrong type (if we can access that)
// @TODO: disable if nothing in clipboard or wrong type (if we can access that)
true,
action: ()=> {
edit_paste(true);
@ -467,7 +467,7 @@ window.menus = {
{
item: "New &Blank Session",
action: ()=> {
// TODO: load new empty session in the same browser tab
// @TODO: load new empty session in the same browser tab
let name = prompt("Enter the session name that will be used in the URL for sharing.");
if(typeof name == "string"){
name = name.trim();
@ -518,7 +518,7 @@ window.menus = {
checkbox: {
toggle: ()=> {
if (location.hash.match(/eye-gaze-mode/i)) {
// TODO: confirmation dialog that you could cancel with dwell clicking!
// @TODO: confirmation dialog that you could cancel with dwell clicking!
// if (confirm("This will disable eye gaze mode.")) {
location.hash = location.hash.replace(/eye-gaze-mode,|,eye-gaze-mode/i, "");
// }
@ -537,7 +537,7 @@ window.menus = {
checkbox: {
toggle: ()=> {
if (location.hash.match(/eye-gaze-mode/i)) {
// TODO: confirmation dialog that you could cancel with dwell clicking!
// @TODO: confirmation dialog that you could cancel with dwell clicking!
// if (confirm("This will disable eye gaze mode.")) {
// location.hash = location.hash.replace(/eye-gaze-mode,|,eye-gaze-mode/i, "");
// location.hash = location.hash.replace(/vertical-color-box-mode,|,vertical-color-box-mode/i, "");

View File

@ -112,7 +112,7 @@
else {
// e.g. localStorage is disabled
// (or there's some other error?)
// TODO: show warning with "Don't tell me again" type option
// @TODO: show warning with "Don't tell me again" type option
}
}
});
@ -123,7 +123,7 @@
show_error_message("Failed to retrieve image from local storage:", err);
}
else {
// TODO: DRY with storage manager message
// @TODO: DRY with storage manager message
show_error_message("Please enable local storage in your browser's settings for local backup. It may be called Cookies, Storage, or Site Data.");
}
}
@ -179,7 +179,7 @@
user.color = `hsla(${user.hue}, ${user.saturation}%, ${user.lightness}%, 1)`;
// Unused
user.color_transparent = `hsla(${user.hue}, ${user.saturation}%, ${user.lightness}%, 0.5)`;
// (@TODO) The color used in the toolbar indicating to other users it is selected by this user
// (@TODO) The color (that may be) used in the toolbar indicating to other users it is selected by this user
user.color_desaturated = `hsla(${user.hue}, ${~~(user.saturation*0.4)}%, ${user.lightness}%, 0.8)`;
@ -226,7 +226,7 @@
}
}
start() {
// TODO: how do you actually detect if it's failing???
// @TODO: how do you actually detect if it's failing???
const $w = $FormToolWindow().title("Warning").addClass("dialogue-window");
$w.$main.html("<p>The document may not load. Changes may not save.</p>" +
"<p>Multiuser sessions are public. There is no security.</p>"
@ -537,14 +537,14 @@
}
end_current_session();
// TODO: fix loading duplicately, from popstate and hashchange
// @TODO: fix loading duplicately, from popstate and hashchange
open_from_URI(url, err => {
if(err){
show_resource_load_error_message();
}
// TODO: saved = false;?
// @TODO: saved = false;?
// NOTE: the following is intended to run regardless of error (as opposed to returning if there's an error)
// FIXME: race condition (make the timeout long and try to fix it with a flag or something )
// @FIXME: race condition (make the timeout long and try to fix it with a flag or something )
setTimeout(() => {
// NOTE: this "change" event doesn't *guarantee* there was a change :/
// let alone that there was a user interaction with the currently loaded document

View File

@ -197,7 +197,7 @@ window.simulateRandomGesturesPeriodically = () => {
});
};
let waitThenGo = () => {
// TODO: a button to stop it as well (maybe make "stop drawing randomly" a link button?)
// @TODO: a button to stop it as well (maybe make "stop drawing randomly" a link button?)
$status_text.text("Press Esc to stop drawing randomly.");
if (isAnyMenuOpen()) {
periodicGesturesTimeoutID = setTimeout(waitThenGo, 50);
@ -218,7 +218,7 @@ window.simulateRandomGesturesPeriodically = () => {
$(choose($(".tool-options *"))).trigger("click");
}
if (seededRandom() < pickColorChance) {
// TODO: maybe these should respond to a normal click?
// @TODO: maybe these should respond to a normal click?
let secondary = seededRandom() < 0.5;
const colorButton = choose($(".swatch, .color-button"));
$(colorButton)

View File

@ -1,4 +1,4 @@
// TODO: remove remaining cruft from being compiled from CoffeeScript
// @TODO: remove remaining cruft from being compiled from CoffeeScript
// or maybe replace this module with localforage actually
// (but need to address asynchronous concerns if doing that)

View File

@ -71,7 +71,7 @@ const $Choose = (things, display, choose, is_chosen) => {
return option_canvas;
};
const update = () => {
const selected_color = get_theme() === "modern.css" ? "#0178d7" : "#000080"; // TODO: get from a CSS variable
const selected_color = get_theme() === "modern.css" ? "#0178d7" : "#000080"; // @TODO: get from a CSS variable
$option_container.css({
backgroundColor: is_chosen(thing) ? selected_color : ""
});

View File

@ -718,7 +718,7 @@ window.tools = [{
ctx.fillRect(x, y, w, h);
ctx.restore();
}else{
// TODO: shouldn't that be ~~(stroke_size / 2)?
// @TODO: shouldn't that be ~~(stroke_size / 2)?
ctx.strokeRect(x + stroke_size / 2, y + stroke_size / 2, w - stroke_size, h - stroke_size);
}
}
@ -758,7 +758,7 @@ window.tools = [{
}
}
}else{
if(d < stroke_size * 5.1010101){ // arbitrary 101 (TODO: find correct value (or formula))
if(d < stroke_size * 5.1010101){ // arbitrary number (@TODO: find correct value (or formula))
this.complete(ctx);
}
}
@ -784,7 +784,7 @@ window.tools = [{
const dy = y - ly;
const dt = +(new Date) - lt;
const d = Math.sqrt(dx*dx + dy*dy);
if(d < 4.1010101 && dt < 250){ // arbitrary 101 (TODO: find correct value (or formula))
if(d < 4.1010101 && dt < 250){ // arbitrary 101 (@TODO: find correct value (or formula))
this.complete(ctx);
}else{
// Add the point
@ -1102,7 +1102,7 @@ tools.forEach((tool)=> {
gradient.addColorStop(6/n, "gold");
color = gradient;
}
// TODO: perf: keep this canvas around too
// @TODO: perf: keep this canvas around too
const mask_fill_canvas = make_canvas(tool.mask_canvas);
replace_colors_with_swatch(mask_fill_canvas.ctx, color, 0, 0);
ctx.drawImage(mask_fill_canvas, 0, 0);
@ -1199,7 +1199,7 @@ tools.forEach((tool)=> {
gradient.addColorStop(6/n, "gold");
color = gradient;
}
// TODO: perf: keep this canvas around too
// @TODO: perf: keep this canvas around too
const mask_fill_canvas = make_canvas(tool.mask_canvas);
if (previewing && tool.dynamic_preview_cursor) {
const brush = tool.get_brush();

View File

@ -79,7 +79,7 @@
filter:
`hue-rotate(${
Math.sin(Date.now() / 4000)
// TODO: slow down and stop when you pause
// @TODO: slow down and stop when you pause
}turn)`,
});
@ -102,7 +102,7 @@
}turn)`,
transformOrigin: "50% 50%",
transformStyle: "preserve-3d",
// FIXME: interactivity problems (with order elements are considered to have), I think related to preserve-3d
// @FIXME: interactivity problems (with order elements are considered to have), I think related to preserve-3d
});
}
};
@ -112,7 +112,7 @@
document.querySelector(".canvas-area").appendChild(player_placeholder);
$(player_placeholder).css({
position: "absolute",
top: "3px", // TODO: dynamic
top: "3px", // @TODO: dynamic
left: "3px",
mixBlendMode: "multiply",
pointerEvents: "none",
@ -137,7 +137,7 @@
onStateChange: onPlayerStateChange,
},
});
// TODO: attribution for this video!
// @TODO: attribution for this video!
// I mean, you can see the title if you hit spacebar, but
// I could make it wave across the screen behind Paint on the desktop
// I could add a "Song Name?" button that responds "Darude Sandstorm"
@ -154,7 +154,7 @@
// The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
// TODO: pause and resume this timer with the video
// @TODO: pause and resume this timer with the video
setTimeout(() => {
$(rotologo).css({opacity: 1});
}, 14150);
@ -162,7 +162,7 @@
if (event.data == YT.PlayerState.ENDED) {
player.destroy();
player = null;
// TODO: fade to white instead of black, to work with the multiply effect
// @TODO: fade to white instead of black, to work with the multiply effect
// or fade out opacity alternatively
// setTimeout/setInterval and check player.getCurrentTime() for when near the end?
// or we might switch to using soundcloud for the audio and so trigger it with that, with a separate video of just clouds
@ -177,7 +177,7 @@
space_phase_key_handler = e => {
// press space to phase in and out of space phase スペース相 - windows 98 マイクロソフト 『WINTRAP』 X 将来のオペレーティングシステムサウンド 1998 VAPORWAVE
if (e.which === 32) {
// TODO: record player SFX
// @TODO: record player SFX
if (is_theoretically_playing) {
player.pauseVideo();
is_theoretically_playing = false;

View File

@ -90,7 +90,7 @@ html, body, .jspaint {
}
.selection,
.textbox {
display: block !important; /* TODO: reduce overzealous display: flex; */
display: block !important; /* @TODO: reduce overzealous display: flex; */
box-sizing: border-box;
-moz-box-sizing: border-box;
}
@ -99,7 +99,7 @@ html, body, .jspaint {
.textbox > canvas,
.selection > img,
.selection > canvas {
/* TODO: maybe don't include the canvas in the DOM (is it helpful to inspect it tho? it's not critical...) */
/* @TODO: maybe don't include the canvas in the DOM (is it helpful to inspect it tho? it's not critical...) */
opacity: 0;
}
.selection > img,
@ -390,7 +390,7 @@ html, body, .jspaint {
.handle::after {
/* make handles way easier to grab */
content: "";
pointer-events: all; /* TODO: maybe don't have a blanket pointer-events: none; on pseudo elements */
pointer-events: all; /* @TODO: maybe don't have a blanket pointer-events: none; on pseudo elements */
display: block;
position: absolute;
left: 50%;
@ -409,7 +409,7 @@ html, body, .jspaint {
which makes it more reasonable to have the border be a draggable thing.
I'm making the draggable area outside the border for now. */
content: "";
pointer-events: all; /* TODO: maybe don't have a blanket pointer-events: none; on pseudo elements */
pointer-events: all; /* @TODO: maybe don't have a blanket pointer-events: none; on pseudo elements */
display: block;
position: absolute;
left: -10px;
@ -460,12 +460,12 @@ html, body, .jspaint {
width: 200px;
}
/* TODO: part of os-gui */
/* @TODO: part of os-gui */
.os-window {
display: flex;
flex-direction: column;
}
/* TODO: part of os-gui */
/* @TODO: part of os-gui */
.os-window .window-content {
flex: 1;
}
@ -631,7 +631,7 @@ html, body, .jspaint {
margin-right: 8px;
}
#jspaint-version {
/* TODO: separate into a shared.css? (not really layout!) */
/* @TODO: separate into a shared.css? (not really layout!) */
font-size: 0.6em;
color: #7b7b7b;
}

View File

@ -52,7 +52,7 @@ body,
background: var(--Hilight);
}
.useless-handle {
background: var(--HilightText); /* TODO: --ButtonHilight? --Window? */
background: var(--HilightText); /* @TODO: --ButtonHilight? --Window? */
box-shadow: 1px 1px 0 var(--Hilight) inset;
}
.resize-ghost {
@ -164,14 +164,14 @@ body,
top: 0px;
right: 0px;
bottom: 0px;
/* TODO: ButtonAlternateFace? */
/* @TODO: ButtonAlternateFace? */
border: 1px solid var(--ButtonFace);
}
.current-colors,
.color-button {
border-top: 1px solid var(--ButtonShadow);
border-left: 1px solid var(--ButtonShadow);
/* TODO: var(--ButtonAlternateFace)? */
/* @TODO: var(--ButtonAlternateFace)? */
border-right: 1px solid var(--ButtonFace);
border-bottom: 1px solid var(--ButtonFace);
/*box-shadow: 1px 1px 0px var(--ButtonDkShadow) inset;*/
@ -332,7 +332,7 @@ body,
input[type=text],
input[type=url] {
/* TODO: fancy 3d inset border (might need a surrounding element because pseudo elements won't work with input) */
/* @TODO: fancy 3d inset border (might need a surrounding element because pseudo elements won't work with input) */
/* I guess an image border could work; maybe I should be using (svg) image borders for stuff */
/* (css inset border style doesn't look good and isn't consistent between browsers) */
border: 1px solid gray;

View File

@ -205,7 +205,7 @@ body {
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5) inset;
}
/* TODO: padding/margin on the top at least when in the sidebar */
/* @TODO: padding/margin on the top at least when in the sidebar */
.tools {
width: 50px;
}
@ -241,8 +241,8 @@ body,
}
/* NOTE: copy/pasted from classic.css */
/* TODO: actually show a preview of the component itself when dragging for the modern theme */
/* TODO: cursor maybe? just when already dragging? */
/* @TODO: actually show a preview of the component itself when dragging for the modern theme */
/* @TODO: cursor maybe? just when already dragging? */
.component-ghost.dock {
outline: 1px solid black;
/*outline: 1px solid invert;*/
@ -270,7 +270,7 @@ body,
}
.help-window iframe {
border: 0;
/* TODO ideally, apply a padding: 16px on the body in the iframe, except for on the landing page (which has a background) */
/* @TODO ideally, apply a padding: 16px on the body in the iframe, except for on the landing page (which has a background) */
}
.help-window ul.contents {
padding: 16px;
@ -287,7 +287,7 @@ body,
cursor: pointer;
}
.help-window li:before {
/* TODO: more modern icons */
/* @TODO: more modern icons */
background-image: url("../../images/help-icons.png");
}
.help-window .item.selected {

View File

@ -18,6 +18,6 @@
}
.menu-hotkey {
/* TODO: when actually supporting menu navigation hotkeys, enable if accessing the menus with the keyboard */
/* @TODO: when actually supporting menu navigation hotkeys, enable if accessing the menus with the keyboard */
text-decoration: none;
}