Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

388 firefox cannot save or load files fix #390

Merged
merged 8 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"firefox-devtools.vscode-firefox-debug",
"streetsidesoftware.code-spell-checker"
]
}
19 changes: 13 additions & 6 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Chrome Vite Debug",
"url": "http://localhost:5173/",
"webRoot": "${workspaceRoot}/src",
//"sourceMaps": true,
},
{
"type": "msedge",
"name": "Edge Vite Debug",
"request": "launch",
"name": "Edge Vite Debug",
"url": "http://localhost:5173/",
"webRoot": "${workspaceFolder}/src"
},
{
"type": "chrome",
"type": "firefox",
"request": "launch",
"name": "Chrome Vite Debug",
"name": "Firefox Vite Debug",
"url": "http://localhost:5173/",
"webRoot": "${workspaceRoot}/src",
//"sourceMaps": true,
}
"webRoot": "${workspaceFolder}/src"
},
]
}
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"homepage": "https://github.com/RAIRLab/PeirceMyHeart#readme",
"devDependencies": {
"@types/file-saver": "^2.0.7",
"@types/node": "20.12.8",
James-Oswald marked this conversation as resolved.
Show resolved Hide resolved
"@types/wicg-file-system-access": "^2023.10.5",
"gts": "^5.3.0",
Expand All @@ -43,6 +44,7 @@
"vitest": "^1.6.0"
},
"dependencies": {
"file-saver": "^2.0.5",
"fork-awesome": "^1.2.0",
"theme-change": "^2.5.0"
}
Expand Down
124 changes: 123 additions & 1 deletion src/AEG-IO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@
* @author Anusha Tiwari
*/

import {TreeContext} from "./TreeContext";
import {redrawProof, redrawTree} from "./SharedToolUtils/DrawUtils";
import {appendStep} from "./ProofHistory/ProofHistory";

import {AEGTree} from "./AEG/AEGTree";
import {AtomNode} from "./AEG/AtomNode";
import {CutNode} from "./AEG/CutNode";
import {Ellipse} from "./AEG/Ellipse";
import {Point} from "./AEG/Point";
import {ProofModeMove, ProofModeNode} from "./ProofHistory/ProofModeNode";

//Cross-browser file saving library.
import FileSaver from "file-saver";

/**
* Describes The Sheet of Assertion in JSON files.
*/
Expand Down Expand Up @@ -146,7 +153,7 @@ function toCut(cutData: cutObj): CutNode {
}

/**
* Parses the incoming AtomObject and returns and equivalent AtomNode.
* Parses the incoming AtomObject and returns an equivalent AtomNode.
*
* @param atomData Incoming AtomObject.
* @returns AtomNode equivalent of atomData.
Expand All @@ -158,3 +165,118 @@ function toAtom(atomData: atomObj): AtomNode {

return new AtomNode(identifier, origin, atomData.internalWidth, atomData.internalHeight);
}

/**
* Creates and returns the json string of the given AEG Tree object.
* Uses tab characters as delimiters.
*
* @param treeData An AEG Tree object.
* @returns json string of treeData.
*/
export function aegJsonString(treeData: AEGTree | ProofModeNode[]): string {
return JSON.stringify(treeData, null, "\t");
}

/**
* Calls appropriate methods to save the current AEGTree as a file.
*/
export async function saveMode(): Promise<void> {
let name: string;
let data: AEGTree | ProofModeNode[];

if (TreeContext.modeState === "Draw") {
name = TreeContext.tree.toString();
data = TreeContext.tree;
} else {
if (TreeContext.proof.length === 1) {
name = "One-Step Proof";
} else {
name =
TreeContext.proof[0].tree.toString() +
" PROVES " +
TreeContext.getLastProofStep().tree.toString();
}
data = TreeContext.proof;
}

//Errors caused by file handler or HTML download element should not be displayed.
try {
//Dialog based download
if ("showSaveFilePicker" in window) {
const saveHandle = await window.showSaveFilePicker({
excludeAcceptAllOption: true,
suggestedName: name,
startIn: "downloads",
types: [{accept: {"text/json": [".json"]}}],
});
saveFile(saveHandle, data);
} else {
//Fallback to immediate download if showSaveFilePicker is not supported.
const blob = new Blob([aegJsonString(data)], {type: "text/json"});
FileSaver(blob, name + ".json");
}
} catch (error) {
//Catch error but do nothing. Discussed in Issue #247.
}
}

function readFile(file: File) {
const reader = new FileReader();
reader.addEventListener("load", () => {
const aegData = reader.result;
if (typeof aegData === "string") {
const loadData = loadFile(TreeContext.modeState, aegData);
if (TreeContext.modeState === "Draw") {
//Loads data.
TreeContext.tree = loadData as AEGTree;
//Redraws tree which is now the parsed loadData.
redrawTree(TreeContext.tree);
} else if (TreeContext.modeState === "Proof") {
//Clears current proof.
TreeContext.clearProof();
//Loads data for the new proof.
TreeContext.proof = loadData as ProofModeNode[];
//Removes default start step.
document.getElementById("Row: 1")?.remove();
//Adds button for each step of the loaded proof to the history bar.
for (let i = 0; i < TreeContext.proof.length; i++) {
appendStep(TreeContext.proof[i], i + 1);
}
TreeContext.currentProofStep = TreeContext.proof[TreeContext.proof.length - 1];
redrawProof();
}
} else {
console.log("Loading failed because reading the file was unsuccessful.");
}
});
reader.readAsText(file);
}

/**
* Calls the appropriate methods to load files and convert them to equivalent AEGTrees.
*/
export async function loadMode(): Promise<void> {
try {
if ("showOpenFilePicker" in window) {
const [fileHandle] = await window.showOpenFilePicker({
excludeAcceptAllOption: true,
multiple: false,
startIn: "downloads",
types: [{accept: {"text/json": [".json"]}}],
});
const file = await fileHandle.getFile();
readFile(file);
} else {
const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = ".json";
fileInput.addEventListener("change", () => {
const file = fileInput.files?.item(0);
readFile(file!);
});
fileInput.click();
}
} catch (error) {
//Do nothing.
}
}
4 changes: 2 additions & 2 deletions src/SharedToolUtils/DrawUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @author Anusha Tiwari
*/

import {aegStringify} from "../index";
import {aegJsonString} from "../AEG-IO";
import {AEGTree} from "../AEG/AEGTree";
import {AtomNode} from "../AEG/AtomNode";
import {CutNode} from "../AEG/CutNode";
Expand Down Expand Up @@ -174,7 +174,7 @@ export function redrawTree(tree: AEGTree, color?: string): void {
cutDisplay.innerHTML = tree.toString();
cleanCanvas();
redrawCut(tree.sheet, color);
window.treeString = aegStringify(tree);
window.treeString = aegJsonString(tree);
}

/**
Expand Down
Loading