c6482c396d
- Nouvelle catégorie Favoris: recuperation des favoris depuis Project.gfx (getFavorites.dg5) - Pages menuFavorites.dg5 et showDataFav.dg5 + bibliothèques JSZip/jQuery - Navigation index.dg5: ajout de la catégorie Favoris - Correctif override.dg5: exclusion des points /services/subnet - Bump version 2.2 et description "Alternative to Command" - Mise a jour README (doc Favoris + changelog)
154 lines
6.0 KiB
HTML
154 lines
6.0 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<script type='text/javascript' src='jquery-3.7.1.min.js'></script>
|
|
<script type='text/javascript' src='jszip.min.js'></script>
|
|
<script type='text/javascript' src='jszip-utils.min.js'></script>
|
|
<script type='text/javascript' src='dgframe.js'></script>
|
|
</head>
|
|
<body>
|
|
<div id="fetch"></div>
|
|
<script type='text/javascript'>
|
|
"use strict";
|
|
let zipSource = "";
|
|
let fileContent;
|
|
let blacklistFiles = "";
|
|
let blacklistSet = new Set();
|
|
let dgParams = {
|
|
"zipSource": function(val) {
|
|
zipSource = val;
|
|
unzip(zipSource);
|
|
},
|
|
"blacklistFiles": function(val) {
|
|
blacklistFiles = val;
|
|
blacklistSet = parseBlacklist(val);
|
|
},
|
|
"fileContent": function(val) {
|
|
fileContent = val;
|
|
}
|
|
};
|
|
|
|
// "chemin1,chemin2,..." -> Set de chemins normalises (slashes en /)
|
|
function parseBlacklist(str) {
|
|
let set = new Set();
|
|
if (!str) {
|
|
return set;
|
|
}
|
|
str.split(",").forEach(function(p) {
|
|
let norm = p.trim().replace(/\\/g, "/");
|
|
if (norm) {
|
|
set.add(norm);
|
|
}
|
|
});
|
|
return set;
|
|
}
|
|
|
|
// Prepare la donnee a charger par JSZip selon la forme recue.
|
|
// JSZip.loadAsync accepte aussi bien une chaine binaire qu'un Uint8Array.
|
|
function toZipData(input) {
|
|
if (typeof input === "string") {
|
|
let trimmed = input.trim();
|
|
|
|
// Reponse JSON {"binary":"<base64>"} -> decoder le base64
|
|
if (trimmed.charAt(0) === "{") {
|
|
let base64 = JSON.parse(trimmed).binary;
|
|
let bin = atob(base64);
|
|
let out = new Uint8Array(bin.length);
|
|
for (let i = 0; i < bin.length; i++) {
|
|
out[i] = bin.charCodeAt(i);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
// Tableau d'octets en texte "[123,34,...]"
|
|
if (trimmed.charAt(0) === "[") {
|
|
return Uint8Array.from(JSON.parse(trimmed));
|
|
}
|
|
|
|
// Zip brut en chaine binaire (commence par "PK") -> JSZip l'accepte tel quel
|
|
return input;
|
|
}
|
|
|
|
// ArrayBuffer / TypedArray / tableau d'octets -> JSZip l'accepte tel quel
|
|
return input;
|
|
}
|
|
|
|
// Octets -> base64 (navigateur)
|
|
function bytesToBase64(bytes) {
|
|
let bin = "";
|
|
for (let i = 0; i < bytes.length; i++) {
|
|
bin += String.fromCharCode(bytes[i]);
|
|
}
|
|
return btoa(bin);
|
|
}
|
|
|
|
// Type MIME a partir de l'extension du fichier
|
|
function mimeFromName(name) {
|
|
let ext = name.split(".").pop().toLowerCase();
|
|
let map = {
|
|
png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg",
|
|
gif: "image/gif", bmp: "image/bmp", webp: "image/webp",
|
|
ico: "image/x-icon", svg: "image/svg+xml"
|
|
};
|
|
return map[ext] || "application/octet-stream";
|
|
}
|
|
|
|
// Decode le contenu d'un fichier selon son encodage reel.
|
|
// Texte: UTF-16 (BOM) ou UTF-8. Binaire (image): data URI base64 pour <img src="">.
|
|
function decodeContent(bytes, name) {
|
|
if (bytes.length >= 2 && bytes[0] === 0xFF && bytes[1] === 0xFE) {
|
|
return new TextDecoder("utf-16le").decode(bytes);
|
|
}
|
|
if (bytes.length >= 2 && bytes[0] === 0xFE && bytes[1] === 0xFF) {
|
|
return new TextDecoder("utf-16be").decode(bytes);
|
|
}
|
|
try {
|
|
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
} catch (e) {
|
|
return "data:" + mimeFromName(name) + ";base64," + bytesToBase64(bytes);
|
|
}
|
|
}
|
|
|
|
function unzip(source) {
|
|
let zipData;
|
|
try {
|
|
zipData = toZipData(source);
|
|
} catch (e) {
|
|
console.log("Erreur de decodage de l'entree:", e);
|
|
return;
|
|
}
|
|
|
|
JSZip.loadAsync(zipData)
|
|
.then(function(zip) {
|
|
let promises = [];
|
|
|
|
zip.forEach(function (relativePath, zipEntry) {
|
|
if (zipEntry.dir) {
|
|
return;
|
|
}
|
|
// Exclu: ni dans la table, ni chargement du contenu (memoire)
|
|
if (blacklistSet.has(relativePath.replace(/\\/g, "/"))) {
|
|
return;
|
|
}
|
|
promises.push(
|
|
zipEntry.async("uint8array").then(function(bytes) {
|
|
return {
|
|
name: zipEntry.name.split("/").pop().split("\\").pop(),
|
|
path: relativePath,
|
|
content: decodeContent(bytes, zipEntry.name)
|
|
};
|
|
})
|
|
);
|
|
});
|
|
|
|
return Promise.all(promises);
|
|
})
|
|
.then(function success(table) {
|
|
dgUpdateParams({ 'fileContent': JSON.stringify(table, null, 2) });
|
|
}, function error(e) {
|
|
console.log("Erreur de lecture du zip:", e);
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |