Can't load image from address starting with "blob:".
${ firefox ? `Try "Copy Image" instead of "Copy Image Location".
` : `Try "Copy image" instead of "Copy image address".
` } `); } else if (error.code === "html-not-image") { $w.$main.html(`Address points to a web page, not an image file.
Try copying and pasting an image instead of a URL.
`); } else if (error.code === "decode-fail") { $w.$main.html(`Address doesn't point to an image file of a supported format.
Try copying and pasting an image instead of a URL.
`); } else { $w.$main.html(`Failed to load image from URL.
Check your browser's devtools for details.
`); } $w.$main.css({maxWidth: "500px"}); $w.$Button(localize("OK"), () => { $w.close(); }); $w.center(); } let $about_paint_window; const $about_paint_content = $("#about-paint"); let $news_window; const $this_version_news = $("#news"); let $latest_news = $this_version_news; // not included directly in the HTML as a simple way of not showing it if it's loaded with fetch // (...not sure how to phrase this clearly and concisely...) // "Showing the news as of this version of JS Paint. For the latest, see jspaint.app" if (location.origin !== "https://jspaint.app") { $this_version_news.prepend( $("For the latest news, visit jspaint.app
") .css({padding: "8px 15px"}) ); } function show_about_paint(){ if($about_paint_window){ $about_paint_window.close(); } $about_paint_window = $ToolWindow().title(localize("About Paint")); if (is_pride_month) { $("#paint-32x32").attr("src", "./images/icons/gay-es-paint-32x32-light-outline.png"); } $about_paint_window.$content.append($about_paint_content.show()).css({padding: "15px"}); $("#maybe-outdated-view-project-news").removeAttr("hidden"); $("#failed-to-check-if-outdated").attr("hidden", "hidden"); $("#outdated").attr("hidden", "hidden"); $about_paint_window.center(); $about_paint_window.center(); // @XXX - but it helps tho $("#refresh-to-update").on("click", (event)=> { event.preventDefault(); location.reload(); }); $("#view-project-news").on("click", ()=> { show_news(); }); $("#checking-for-updates").removeAttr("hidden"); const url = // "."; // "test-news-newer.html"; "https://jspaint.app"; fetch(url) .then((response)=> response.text()) .then((text)=> { const parser = new DOMParser(); const htmlDoc = parser.parseFromString(text, "text/html"); $latest_news = $(htmlDoc).find("#news"); const $latest_entries = $latest_news.find(".news-entry"); const $this_version_entries = $this_version_news.find(".news-entry"); if (!$latest_entries.length) { $latest_news = $this_version_news; throw new Error(`No news found at fetched site (${url})`); } function entries_contains_update($entries, id) { return $entries.get().some((el_from_this_version)=> id === el_from_this_version.id ); } // @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) ); entries_new_in_this_version = // i.e. in development, when updating the news $this_version_entries.get().filter((el_from_latest)=> !entries_contains_update($latest_entries, el_from_latest.id) ); if (entries_newer_than_this_version.length > 0) { $("#outdated").removeAttr("hidden"); } else if(entries_new_in_this_version.length > 0) { $latest_news = $this_version_news; // show this version's news for development } $("#checking-for-updates").attr("hidden", "hidden"); update_css_classes_for_conditional_messages(); }).catch((exception)=> { $("#failed-to-check-if-outdated").removeAttr("hidden"); $("#checking-for-updates").attr("hidden", "hidden"); update_css_classes_for_conditional_messages(); window.console && console.log("Couldn't check for updates.", exception); }); } // show_about_paint(); // for testing function update_css_classes_for_conditional_messages() { $(".on-dev-host, .on-third-party-host, .on-official-host").hide(); if (location.hostname.match(/localhost|127.0.0.1/)) { $(".on-dev-host").show(); } else if (location.hostname.match(/jspaint.app/)) { $(".on-official-host").show(); } else { $(".on-third-party-host").show(); } $(".navigator-online, .navigator-offline").hide(); if (navigator.onLine) { $(".navigator-online").show(); } else { $(".navigator-offline").show(); } } function show_news(){ if($news_window){ $news_window.close(); } $news_window = $ToolWindow().title("Project News"); // const $latest_entries = $latest_news.find(".news-entry"); // const latest_entry = $latest_entries[$latest_entries.length - 1]; // window.console && console.log("LATEST MEWS:", $latest_news); // window.console && console.log("LATEST ENTRY:", latest_entry); const $latest_news_style = $latest_news.find("style"); $this_version_news.find("style").remove(); $latest_news.append($latest_news_style); // in case $this_version_news is $latest_news $news_window.$content.append($latest_news.removeAttr("hidden")); $news_window.center(); $news_window.center(); // @XXX - but it helps tho } // @TODO: DRY between these functions and open_from_* functions further? // function paste_image_from_URI(uri, callback){ // load_image_from_URI(uri, (err, img)=> { // if(err){ return callback(err); } // paste(img); // }); // }; function paste_image_from_file(file){ const blob_url = URL.createObjectURL(file); // paste_image_from_URI(blob_url); load_image_from_URI(blob_url, (error, img) => { if(error){ return show_resource_load_error_message(error); } paste(img); URL.revokeObjectURL(blob_url); }); } function paste_from_file_select_dialog(){ get_FileList_from_file_select_dialog(files => { for (const file of files) { if(file.type.match(/^image/)){ paste_image_from_file(file); return; } } if(files.length > 1){ show_error_message(`None of the files selected appear to be images.`); }else{ show_error_message(`File selected does not appear to be an image.`); } }); } function paste(img){ if(img.width > canvas.width || img.height > canvas.height){ const $w = new $FormToolWindow().addClass("dialogue-window"); $w.title(localize("Paint")); $w.$main.html(` ${localize("The image in the clipboard is larger than the bitmap.")}Press Ctrl+Shift+Y at any time to open this window.
`); const $history_view = $w.$content.find(".history-view"); let previous_scroll_position = 0; let rendered_$entries = []; function render_tree_from_node(node) { const $entry = $(`Tried to save file, but file was empty.
Try again, or if the problem persists, report here: Issue #118 `); $w.$main.css({maxWidth: "500px"}); $w.$Button(localize("OK"), () => { $w.close(); }); $w.center(); } } function show_multi_user_setup_dialog(from_current_document){ const $w = $FormToolWindow().title("Multi-User Setup").addClass("dialogue-window"); $w.$main.html(` ${from_current_document ? "
This will make the current document public.
" : ""}Enter the session name that will be used in the URL for sharing:
`); const $session_name = $w.$main.find("#session-name"); $w.$main.css({maxWidth: "500px"}); $w.$Button("Start", () => { let name = $session_name.val().trim(); if(name == ""){ show_error_message("The session name cannot be empty."); // }else if(name.match(/[./[\]#$]/)){ // show_error_message("The session name cannot contain any of ./[]#$"); // }else if(name.match(/\s/)){ // show_error_message("The session name cannot contain spaces."); }else if($session_name.is(":invalid")){ show_error_message("The session name must be made from only numbers, letters, and hyphens."); }else{ if (from_current_document) { change_url_param("session", name); } else { // @TODO: load new empty session in the same browser tab // (or at least... keep settings like vertical-color-box-mode?) window.open(`${location.origin}${location.pathname}#session:${name}`); } $w.close(); } }); $w.$Button(localize("Cancel"), () => { $w.close(); }); $w.center(); $session_name.focus(); }