A massive commit
I'm finally going to continue working on this and commit like I should.
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 73 KiB |
BIN
DremJS-Background_Classic.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
196
agenda-wm.js
|
@ -11,24 +11,45 @@
|
|||
* "So, what's on the agenda?"
|
||||
* (C) Innovation Inc. 2020
|
||||
*/
|
||||
var detector = new MobileDetect(window.navigator.userAgent)
|
||||
var highestId = 0;
|
||||
var CurrentTaskbarApp = "";
|
||||
|
||||
function initAgendaWM() {
|
||||
console.log("Initializing Agenda WM");
|
||||
startTime();
|
||||
console.log("Starting widgets");
|
||||
startWidgets();
|
||||
makeDraggable();
|
||||
console.log("Agenda WM Initialized");
|
||||
//var detector = new MobileDetect(window.navigator.userAgent)
|
||||
if(!(detector.mobile())) {
|
||||
console.log("Initializing Agenda WM");
|
||||
startTime();
|
||||
console.log("Starting widgets");
|
||||
startWidgets();
|
||||
makeDraggable();
|
||||
console.log("Agenda WM Initialized");
|
||||
} else {
|
||||
initAgendaMobile();
|
||||
}
|
||||
} // Initialize Agenda
|
||||
|
||||
// Desktop version of Agenda
|
||||
|
||||
function makeDraggable() {
|
||||
$(".framewrap")
|
||||
.draggable()
|
||||
.resizable();
|
||||
} // Makes all applications with the framewrap class draggable. Has to be ran every time applications are launched or things get sticky.
|
||||
|
||||
/*function moveToFront(app) {
|
||||
var application = document.getElementById(app);
|
||||
if(openflag==true)
|
||||
application.style.display = "block";
|
||||
openflag = true;
|
||||
$('.framewrap').css('z-index', 1);
|
||||
$('#' + app).css('z-index', 9999);
|
||||
console.log("Move to front");
|
||||
} // Move a clicked application to the front*/
|
||||
|
||||
function moveToFront(app) {
|
||||
$('.framewrap').css('z-index', 1);
|
||||
$('.framewrap').css('z-index', 1);
|
||||
$('.framewrapMobile').css('z-index', 1);
|
||||
$('#' + app).css('z-index', 9999);
|
||||
} // Move a clicked application to the front
|
||||
|
||||
|
@ -63,16 +84,30 @@ function openApplication(app, width, height, appIcon, filename) {
|
|||
|
||||
Quite frustrating to work with, but it works. I'll make it fancier later, but right now it is good enough.
|
||||
*/
|
||||
var application="<div onclick=\"moveToFront('" + i + "')\" name='" + app + "' id='" + i + "' class='framewrap' style='width:" + width + "px; height:" + height + "px'><input type='button' onclick=\"closeApplication('" + i + "')\" value='X' /><input type='button' onclick=\"maximizeApplication('" + i + "')\" value='\u25A1' /><input type='button' onclick=\"minimizeApplication('" + i + "')\" value='_' /><iframe class='appFrame' src='apps/" + app + "/" + file + "'></iframe></div>";
|
||||
var taskbarApp="<div id='task" + i + "' onclick=\"moveToFront('" + i + "')\" class='taskbarApps'><img src='apps/" + app + "/" + appIcon + "' style='width:32px;height:32px' align='middle' /></div>";
|
||||
var parent=document.getElementById('appContainer');
|
||||
//var application="<div onclick=\"moveToFront('" + i + "')\" name='" + app + "' id='" + i + "' class='framewrap' style='width:" + width + "px; height:" + height + "px'><td nowrap><input type='button' onclick=\"closeApplication('" + i + "')\" value='X' /><input type='button' onclick=\"maximizeApplication('" + i + "')\" value='\u25A1' /><input type='button' onclick=\"minimizeApplication('" + i + "')\" value='_' /><p>Application Name</p></td><iframe class='appFrame' src='apps/" + app + "/" + file + "'></iframe></div>";
|
||||
//var taskbarApp="<div id='task" + i + "' onclick=\"moveToFront('" + i + "')\" class='taskbarApps'><img src='apps/" + app + "/" + appIcon + "' style='width:32px;height:32px' align='middle' /></div>";
|
||||
if (!(detector.mobile())) {
|
||||
var application="<div onclick=\"moveToFront('" + i + "')\" name='" + app + "' id='" + i + "' class='framewrap' style='width:" + width + "px; height:" + height + "px'><input type='button' onclick=\"closeApplication('" + i + "')\" value='X' /><input type='button' onclick=\"maximizeApplication('" + i + "')\" value='\u25A1' /><input type='button' onclick=\"minimizeApplication('" + i + "')\" value='_' /><iframe name='" + i + "' id='app" + i + "' class='appFrame' src='apps/" + app + "/'></iframe></div>";
|
||||
var taskbarApp="<div onmousedown='SetCurrentTaskbarApp(" + i + ")' onmouseup='SetCurrentTaskbarApp(\"\")' id='task" + i + "' onclick=\"minimizeApplication('" + i + "')\" class='taskbarApps'><img src='apps/" + app + "/" + appIcon + "' style='width:32px;height:32px' align='middle' /></div>";
|
||||
} else {
|
||||
var application="<div onclick=\"moveToFront('" + i + "')\" name='" + app + "' id='" + i + "' class='framewrapMobile' style='width:" + width + "px; height:" + height + "px'><input type='button' onclick=\"showContextMenu('app" + i + "')\" value='▼' /><iframe name='" + i + "' id='app" + i + "' class='appFrameMobile' src='apps/" + app + "/'></iframe></div>";
|
||||
var taskbarApp="<div tabindex='0' onmousedown='SetCurrentTaskbarApp(" + i + ")' id='task" + i + "' onclick=\"moveToFront('" + i + "'); SetCurrentTaskbarApp(" + i + ")\" class='taskbarApps'><img src='apps/" + app + "/" + appIcon + "' style='width:32px;height:32px' align='middle' /></div>";
|
||||
// touchstart='SetCurrentTaskbarApp(" + i + ")' touchend='SetCurrentTaskbarApp(\"\")'
|
||||
// onmouseup='SetCurrentTaskbarApp(\"\")'
|
||||
}
|
||||
var parent=document.getElementById('appContainer');
|
||||
parent.insertAdjacentHTML('beforeend', application);
|
||||
var parent=document.getElementById('taskbarApps');
|
||||
parent.insertAdjacentHTML('beforeend', taskbarApp);
|
||||
if (width == "max" || height == "max")
|
||||
parent.insertAdjacentHTML('beforeend', taskbarApp);
|
||||
if (width == "max" || height == "max")
|
||||
maximizeApplication(i);
|
||||
moveToFront(i);
|
||||
makeDraggable();
|
||||
makeDraggable();
|
||||
if (detector.mobile()) {
|
||||
maximizeApplication(i);
|
||||
}
|
||||
if (i>highestId)
|
||||
highestId=i;
|
||||
} // Opens an application.
|
||||
function openWidget(widget, filename) {
|
||||
if (filename == undefined) {
|
||||
|
@ -84,7 +119,7 @@ function openApplication(app, width, height, appIcon, filename) {
|
|||
// Get the first available application ID.
|
||||
while ($('#' + i).length)
|
||||
i++;
|
||||
var newWidget = "<div name='" + widget + "' id='" + i + "' class='framewrap' style='width:300px;height:300px;'><iframe class='appFrame' src='widgets/" + widget + "/" + file + "'></iframe></div>";
|
||||
var newWidget = "<div name='" + widget + "' id='" + i + "' class='framewrap' style='width:300px;height:300px;'><br /><iframe class='appFrame' src='widgets/" + widget + "/" + file + "'></iframe></div>";
|
||||
var parent=document.getElementById('appContainer');
|
||||
parent.insertAdjacentHTML('beforeend', newWidget);
|
||||
makeDraggable();
|
||||
|
@ -105,38 +140,58 @@ function openApplication(app, width, height, appIcon, filename) {
|
|||
} // Start all enabled widgets
|
||||
|
||||
function closeApplication(id) {
|
||||
if(idExists(id)) {
|
||||
var application = document.getElementById(id);
|
||||
var taskbarApp = document.getElementById('task' + id);
|
||||
application.parentNode.removeChild(application);
|
||||
if(taskbarApp != null)
|
||||
taskbarApp.parentNode.removeChild(taskbarApp);
|
||||
} else {
|
||||
console.log("Application with ID " + id + " does not exist. Ignoring.");
|
||||
}
|
||||
} // Closes an application.
|
||||
|
||||
function maximizeApplication(id) {
|
||||
document.getElementById(id).setAttribute('style', "height: 92%; width: 99%; top: 42px; left: 0px");
|
||||
} // Maximize application
|
||||
|
||||
function minimizeApplication(id) {
|
||||
if(idExists(id)) {
|
||||
var application = document.getElementById(id);
|
||||
if (application.style.display === "none") {
|
||||
application.style.display = "block";
|
||||
} else {
|
||||
application.style.display = "none";
|
||||
}
|
||||
} // Minimize application
|
||||
|
||||
function idExists(id) {
|
||||
if ($('#' + id).length)
|
||||
return $('#' + id).attr('name');
|
||||
else
|
||||
return false;
|
||||
} // Check if an ID exists
|
||||
var taskbarApp = document.getElementById('task' + id);
|
||||
application.parentNode.removeChild(application);
|
||||
if(taskbarApp != null)
|
||||
taskbarApp.parentNode.removeChild(taskbarApp);
|
||||
} else {
|
||||
console.log("Application with ID " + id + " does not exist. Ignoring.");
|
||||
}
|
||||
} // Closes an application.
|
||||
|
||||
function startTime() {
|
||||
function maximizeApplication(id, DoNotMoveToFront) {
|
||||
if($("#" + id).length) {
|
||||
if(document.getElementById(id).style.display == "none")
|
||||
application.style.display = "block";
|
||||
windowheight = window.innerHeight-42;
|
||||
//document.getElementById(id).setAttribute('style', "height: 92%; width: 99%; top: 42px; left: 0px");
|
||||
document.getElementById(id).setAttribute('style', "height: " + windowheight + "px; width: 100%; top: 42px; left: 0px");
|
||||
if(!DoNotMoveToFront)
|
||||
moveToFront(id);
|
||||
}
|
||||
//document.getElementById(id).setAttribute('style', "height: " + (window.innerHeight-42) + "px; width: " + window.innerHeight + "; top: 42px; left: 0px");
|
||||
} // Maximize application
|
||||
|
||||
/*function minimizeApplication(id) {
|
||||
var application = document.getElementById(id);
|
||||
if (application.style.display === "none") {
|
||||
application.style.display = "block";
|
||||
} else {
|
||||
application.style.display = "none";
|
||||
}
|
||||
openflag=false;
|
||||
console.log("Minimize");
|
||||
} // Minimize application*/
|
||||
|
||||
function minimizeApplication(id, DisallowUnminimize) {
|
||||
var application = document.getElementById(id);
|
||||
if (application.style.display === "none" && !DisallowUnminimize) {
|
||||
application.style.display = "block";
|
||||
} else {
|
||||
application.style.display = "none";
|
||||
}
|
||||
} // Minimize application
|
||||
|
||||
function idExists(id) {
|
||||
if ($('#' + id).length)
|
||||
return $('#' + id).attr('name');
|
||||
else
|
||||
return false;
|
||||
} // Check if an ID exists
|
||||
|
||||
function startTime() {
|
||||
var today = new Date();
|
||||
var h = today.getHours();
|
||||
var m = today.getMinutes();
|
||||
|
@ -146,12 +201,12 @@ function startTime() {
|
|||
document.getElementById('txt').innerHTML =
|
||||
h + ":" + m + ":" + s;
|
||||
var t = setTimeout(startTime, 500);
|
||||
} // Tick tock, Mr. Wick...
|
||||
} // Tick tock, Mr. Wick...
|
||||
|
||||
function checkTime(i) {
|
||||
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
|
||||
return i;
|
||||
}
|
||||
function checkTime(i) {
|
||||
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
|
||||
return i;
|
||||
}
|
||||
|
||||
/*function returnStatus(req, status) {
|
||||
//console.log(req);
|
||||
|
@ -174,3 +229,46 @@ function fetchStatus(address) {
|
|||
client.open("HEAD", address);
|
||||
client.send();
|
||||
}
|
||||
|
||||
// Below are helper functions for making the "Close Application" function in DremJS possible. They may come in handy for other reasons, too.
|
||||
function SetCurrentTaskbarApp(id, AutoDisable) {
|
||||
//console.log("SET: " + id);
|
||||
CurrentTaskbarApp = "" + id;
|
||||
} // Sets or mutates CurrentTaskbarApp
|
||||
|
||||
function GetCurrentTaskbarApp() {
|
||||
//console.log("GET: " + CurrentTaskbarApp);
|
||||
return CurrentTaskbarApp;
|
||||
} // Accessor for CurrentTaskbarApp
|
||||
|
||||
// Mobile version of Agenda
|
||||
|
||||
function initAgendaMobile() {
|
||||
console.log("Initializing Agenda Mobile");
|
||||
startTime();
|
||||
console.log("Starting widgets");
|
||||
startWidgets();
|
||||
makeDraggable();
|
||||
console.log("Agenda Mobile Initialized");
|
||||
}
|
||||
|
||||
function maximizeAllApplications() {
|
||||
for(i=0; i<=highestId; i++)
|
||||
maximizeApplication(i, true);
|
||||
}
|
||||
|
||||
function minimizeAllApplications() {
|
||||
for(i=0; i<=highestId; i++)
|
||||
minimizeApplication(i, true);
|
||||
}
|
||||
|
||||
$(window).resize(function() {
|
||||
if(detector.mobile())
|
||||
maximizeAllApplications();
|
||||
});
|
||||
|
||||
/*function showContextMenu() {
|
||||
try {
|
||||
parent.showContextMenu();
|
||||
} catch(e) { }
|
||||
}*/
|
BIN
apps/Cinema/assets/images/Default.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
apps/Cinema/assets/images/lightbulb-off-black.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
apps/Cinema/assets/images/lightbulb-off-white.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
apps/Cinema/assets/images/lightbulb-on-black.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
apps/Cinema/assets/images/lightbulb-on-white.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
apps/Cinema/cinema.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
238
apps/Cinema/index.php
Normal file
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
$file = "/home/user/Pictures/Default.png";
|
||||
|
||||
function GenerateTagForMedia($path) {
|
||||
global $file;
|
||||
// What even is this massive statement? The answer may shock you.
|
||||
// (it's laziness)
|
||||
if(isset($_REQUEST["action"]) && $_REQUEST["action"] == "shuffle") {
|
||||
return ShuffleMusic();
|
||||
}
|
||||
if(isset($_REQUEST["openfile"])) {
|
||||
if(file_exists($_SERVER["DOCUMENT_ROOT"].$_REQUEST["openfile"]) && !is_dir($_SERVER["DOCUMENT_ROOT"].$_REQUEST["openfile"])) {
|
||||
$mime = mime_content_type($_SERVER["DOCUMENT_ROOT"].$_REQUEST["openfile"]);
|
||||
if(strstr($mime, "video/")){
|
||||
return "<video class='media' controls autoplay>\
|
||||
<source src='".$_REQUEST["openfile"]."' type='".$mime."'>\
|
||||
</video>";
|
||||
// This basically depends on the video tag to support the video and is dumb.
|
||||
}else if(strstr($mime, "image/")){
|
||||
return "<img class='media' src='".$_REQUEST['openfile']."'>";
|
||||
}else if(strstr($mime, "audio/")){
|
||||
return "<audio controls autoplay>\
|
||||
<source src='".$_REQUEST["openfile"]."' type='".$mime."'>\
|
||||
</audio>";
|
||||
}
|
||||
} else {
|
||||
return "<img class='media' src='assets/images/Default.png'>";
|
||||
}
|
||||
} else {
|
||||
return "<img class='media' src='assets/images/Default.png'>";
|
||||
}
|
||||
}
|
||||
|
||||
function ShuffleMusic() {
|
||||
// Build array of all music in the user's Music directory
|
||||
$files = scandir("/home/user/Music/");
|
||||
$music = array();
|
||||
$temp = "";
|
||||
|
||||
// Find all files that have .mp3, .wav, or .ogg (not case sensitive) and put them into the $music array
|
||||
for ($i = 0; $i < count($files); $i++) {
|
||||
if (count($temp) >= 5) {
|
||||
$temp = substr($files[$i], count($files[$i]-4));
|
||||
} else {
|
||||
$temp = "StringTooSmallSkipping";
|
||||
}
|
||||
if($temp == ".mp3" || $temp == ".wav" || $temp == ".ogg") {
|
||||
$music[] = $files[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*if($_REQUEST["action"] == "shuffle") {
|
||||
ShufleMusic();
|
||||
}*/
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Calibri;
|
||||
background-color: white;
|
||||
}
|
||||
.container {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
padding: 0px;
|
||||
}
|
||||
.left {
|
||||
width: 30%;
|
||||
float: left;
|
||||
}
|
||||
.right {
|
||||
margin-left: 5%;
|
||||
}
|
||||
.openDialog {
|
||||
position: absolute;
|
||||
background: #D3D3D3;
|
||||
top: 5%;
|
||||
left: 5%;
|
||||
width: 90%;
|
||||
padding: 5px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aboutDialog {
|
||||
position: absolute;
|
||||
background: #D3D3D3;
|
||||
top: 5%;
|
||||
left: 5%;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
padding: 5px;
|
||||
display: none;
|
||||
}
|
||||
.actionbar {
|
||||
height: 42px;
|
||||
width: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
.actionbarbutton {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 10px;
|
||||
}
|
||||
.media {
|
||||
height: 95%;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="Init();">
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
function GetDremJSMenuFunctions() {
|
||||
return [
|
||||
["Open", "OpenDocumentDialog();"],
|
||||
["<hr />", ""],
|
||||
["Shuffle", "ShuffleMusic();"],
|
||||
["<hr />", ""],
|
||||
["Toggle Light", "ToggleLight();"],
|
||||
["<hr />", ""],
|
||||
["About", "About();"]
|
||||
];
|
||||
}
|
||||
|
||||
CurrentFile = "/home/user/";
|
||||
var MediaTag = "";
|
||||
|
||||
function Init() {
|
||||
//document.getElementById("writingto").innerHTML = "Writing to: " + CurrentFile;
|
||||
MediaTag = "<?php echo GenerateTagForMedia("/home/user/Pictures/Default.png"); ?>";
|
||||
document.getElementById("open").value = CurrentFile;
|
||||
|
||||
document.getElementById('MediaBox').innerHTML=MediaTag;
|
||||
}
|
||||
|
||||
function OpenDocumentDialog() {
|
||||
document.getElementById("openDialog").style.display = "block";
|
||||
}
|
||||
|
||||
function OpenDocument() {
|
||||
/*$.ajax({
|
||||
url : window.location.href,
|
||||
type : "POST",
|
||||
data : {action : "open", open : document.getElementById("open").value},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
//console.log(data);// You can see the result which is created in chat.php
|
||||
console.log("Successfully Opened");
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
console.log(textStatus);// if there is an error
|
||||
}
|
||||
});*/
|
||||
//CurrentFile = document.getElementById("open").value;
|
||||
//CancelOpen();
|
||||
//Init();
|
||||
window.location.href = "index.php?action=open&openfile=" + document.getElementById("open").value;
|
||||
}
|
||||
|
||||
function CancelOpen() {
|
||||
document.getElementById("openDialog").style.display = "none";
|
||||
}
|
||||
|
||||
function About() {
|
||||
document.getElementById("aboutDialog").style.display = "block";
|
||||
}
|
||||
|
||||
function CloseAbout() {
|
||||
document.getElementById("aboutDialog").style.display = "none";
|
||||
}
|
||||
|
||||
function ToggleLight() {
|
||||
if (document.getElementsByTagName("body")[0].style.backgroundColor === "black") {
|
||||
document.getElementsByTagName("body")[0].style.backgroundColor = "white";
|
||||
} else {
|
||||
document.getElementsByTagName("body")[0].style.backgroundColor = "black";
|
||||
}
|
||||
}
|
||||
|
||||
function ShuffleMusic() {
|
||||
$.ajax({
|
||||
type:'POST',
|
||||
url:'index.php',
|
||||
data:'action=shuffle',
|
||||
success:function(data) {
|
||||
if(data=="Something") {
|
||||
// Do Something
|
||||
} else {
|
||||
// Do Something
|
||||
}
|
||||
}
|
||||
});
|
||||
window.location.href = "index.php?action=shuffle";
|
||||
}
|
||||
</script>
|
||||
<!--<div id="actionBar" class="actionbar">
|
||||
<div id="light" class="actionbarbutton left">
|
||||
<img style="width:42px;height:42px;" src="assets/images/lightbulb-on-white.png" />
|
||||
</div>
|
||||
</div>-->
|
||||
<center>
|
||||
<div id="MediaBox">
|
||||
|
||||
</div>
|
||||
</center>
|
||||
|
||||
<div id="openDialog" class="openDialog">
|
||||
<p>Input the path to the media file you would like to open. You can use the File Manager to find the path.</p>
|
||||
<!--<form action="index.php" method="POST">
|
||||
<input type="hidden" name="action" value="open" />-->
|
||||
<input type="text" id="open" name="open" size="50" />
|
||||
<input type="submit" id="OpenFile" onclick="OpenDocument()" value="Open File" />
|
||||
<!--</form>-->
|
||||
<input type="button" onclick="CancelOpen()" value="Cancel" />
|
||||
</div>
|
||||
|
||||
<div id="aboutDialog" class="aboutDialog container">
|
||||
<div class="left">
|
||||
<img src="cinema.png" style="width:128px;height:128px" />
|
||||
</div>
|
||||
<div class="right">
|
||||
<h1>About DremJS Cinema</h1>
|
||||
<h2>Version: 0.1.0b</h2>
|
||||
</div>
|
||||
<p>
|
||||
Open: Opens a media file.<br />
|
||||
Toggle Light: Toggles the background to be white or black (easier on the eyes)<br />
|
||||
</p>
|
||||
<center><input type="button" onclick="CloseAbout()" value="Close" /></center>
|
||||
<p>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
6
apps/Cinema/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Cinema
|
||||
Author: Innovation Inc.
|
||||
Width: 700
|
||||
Height: 450
|
||||
Icon: cinema.png
|
||||
Category: /Media
|
2
apps/Cinema/php_errors.log
Normal file
|
@ -0,0 +1,2 @@
|
|||
[27-Oct-2020 09:43:56 America/Chicago] PHP Parse error: syntax error, unexpected '}' in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/cinema/index.php on line 46
|
||||
[27-Oct-2020 09:45:05 America/Chicago] PHP Notice: Undefined index: action in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/cinema/index.php on line 53
|
BIN
apps/FileManager/filemanager.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
9
apps/FileManager/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!-- File Manager Forwarder -->
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<meta http-equiv="refresh" content="0;url=../../home/user/index.php" />
|
||||
</head>
|
||||
</html>
|
6
apps/FileManager/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: File Manager
|
||||
Author: Innovation Science
|
||||
Width: 700
|
||||
Height: 450
|
||||
Icon: filemanager.png
|
||||
Category: /
|
211
apps/Notepad/index.php
Normal file
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
//if(!isset($_POST["open"])) {
|
||||
$file = "/home/user/Documents/NewFile.txt";
|
||||
//} else {
|
||||
//$file = $_POST["open"];
|
||||
//}
|
||||
function GetFileContents() {
|
||||
global $file;
|
||||
if(isset($_REQUEST["openfile"]))
|
||||
return file_get_contents($_SERVER["DOCUMENT_ROOT"].$_REQUEST["openfile"]);
|
||||
return file_get_contents($_SERVER["DOCUMENT_ROOT"].$file);
|
||||
}
|
||||
|
||||
function SaveDocument() {
|
||||
//$currentUser = $_SERVER["DOCUMENT_ROOT"]."/home/user";
|
||||
$writeto = fopen($_SERVER["DOCUMENT_ROOT"].$_REQUEST["file"], "w");
|
||||
fwrite($writeto, $_REQUEST["text"]);
|
||||
fclose($writeto);
|
||||
}
|
||||
if (isset($_REQUEST["action"])) {
|
||||
if($_REQUEST["action"] == "save") {
|
||||
SaveDocument();
|
||||
} elseif ($_REQUEST["action"] == "open") {
|
||||
global $file;
|
||||
$file = $_REQUEST["openfile"];
|
||||
if(!is_file($_SERVER["DOCUMENT_ROOT"].$file)) {
|
||||
$writeto = fopen($_SERVER["DOCUMENT_ROOT"].$file, "w");
|
||||
fclose($writeto);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Calibri;
|
||||
}
|
||||
.container {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
padding: 0px;
|
||||
}
|
||||
.left {
|
||||
width: 30%;
|
||||
float: left;
|
||||
}
|
||||
.right {
|
||||
margin-left: 5%;
|
||||
}
|
||||
.openDialog {
|
||||
position: absolute;
|
||||
background: #D3D3D3;
|
||||
top: 5%;
|
||||
left: 5%;
|
||||
width: 90%;
|
||||
padding: 5px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aboutDialog {
|
||||
position: absolute;
|
||||
background: #D3D3D3;
|
||||
top: 5%;
|
||||
left: 5%;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
padding: 5px;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="Init();">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script>
|
||||
CurrentFile = "<?php echo $file; ?>";
|
||||
|
||||
function Init() {
|
||||
document.getElementById("writingto").innerHTML = "Writing to: " + CurrentFile;
|
||||
document.getElementById("inputbox").value = "<?php echo GetFileContents(); //echo file_get_contents($_SERVER["DOCUMENT_ROOT"].$file); ?>";
|
||||
document.getElementById("open").value = CurrentFile;
|
||||
}
|
||||
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
function GetDremJSMenuFunctions() {
|
||||
return [
|
||||
["Open", "OpenDocumentDialog();"],
|
||||
["Save", "SaveDocument();"],
|
||||
["<hr />", ""],
|
||||
["Copy", "CopyText();"],
|
||||
["Paste", "PasteText();"],
|
||||
["<hr />", ""],
|
||||
["About", "About();"]
|
||||
];
|
||||
// Scrapped
|
||||
// ["New", "NewDocument();"],
|
||||
// ["Save As...", "SaveDocumentAs();"],
|
||||
// ["Delete", "DeleteSelected();"],
|
||||
}
|
||||
|
||||
function SaveDocument() {
|
||||
//document.getElementById("form").submit();
|
||||
//console.log(document.getElementById("inputbox").value);
|
||||
$.ajax({
|
||||
url : window.location.href,
|
||||
type: "POST",
|
||||
data : {action : "save", text : document.getElementById("inputbox").value, file : CurrentFile},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
//console.log(data);// You can see the result which is created in chat.php
|
||||
console.log("Successfully Saved");
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
console.log(textStatus);// if there is an error
|
||||
}
|
||||
});
|
||||
//Init();
|
||||
}
|
||||
|
||||
function OpenDocumentDialog() {
|
||||
document.getElementById("openDialog").style.display = "block";
|
||||
}
|
||||
|
||||
function OpenDocument() {
|
||||
/*$.ajax({
|
||||
url : window.location.href,
|
||||
type : "POST",
|
||||
data : {action : "open", open : document.getElementById("open").value},
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
//console.log(data);// You can see the result which is created in chat.php
|
||||
console.log("Successfully Opened");
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
console.log(textStatus);// if there is an error
|
||||
}
|
||||
});*/
|
||||
//CurrentFile = document.getElementById("open").value;
|
||||
//CancelOpen();
|
||||
//Init();
|
||||
//console.log(document.getElementById("open").value);
|
||||
window.location.href = "index.php?action=open&openfile=" + document.getElementById("open").value;
|
||||
}
|
||||
|
||||
function CancelOpen() {
|
||||
document.getElementById("openDialog").style.display = "none";
|
||||
}
|
||||
|
||||
function CopyText() {
|
||||
document.execCommand("copy");
|
||||
}
|
||||
|
||||
function PasteText() {
|
||||
box = document.getElementById("inputbox");
|
||||
box.focus();
|
||||
navigator.clipboard.readText()
|
||||
.then(text => {
|
||||
loc = box.value.slice(0, box.selectionStart).length;
|
||||
value = document.getElementById("inputbox").value;
|
||||
document.getElementById("inputbox").value = value.substring(0, loc) + text + value.substring(loc, value.length);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to read clipboard contents: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
function About() {
|
||||
document.getElementById("aboutDialog").style.display = "block";
|
||||
}
|
||||
|
||||
function CloseAbout() {
|
||||
document.getElementById("aboutDialog").style.display = "none";
|
||||
}
|
||||
</script>
|
||||
<!--<form>
|
||||
<label>DremJS Notepad</label>
|
||||
<br />
|
||||
<textarea id="inputbox" name="inputbox" rows="50" columns="500"></textarea>
|
||||
</form>-->
|
||||
<div id="openDialog" class="openDialog">
|
||||
<p>Input the path to the document you would like to open. You can use the File Manager to find the path.</p>
|
||||
<!--<form action="index.php" method="POST">
|
||||
<input type="hidden" name="action" value="open" />-->
|
||||
<input type="text" id="open" name="open" size="50" />
|
||||
<input type="submit" id="OpenFile" onclick="OpenDocument()" value="Open File" />
|
||||
<!--</form>-->
|
||||
<input type="button" onclick="CancelOpen()" value="Cancel" />
|
||||
</div>
|
||||
<div id="aboutDialog" class="aboutDialog container">
|
||||
<div class="left">
|
||||
<img src="notepad.png" style="width:128px;height:128px" />
|
||||
</div>
|
||||
<div class="right">
|
||||
<h1>About DremJS Notepad</h1>
|
||||
<h2>Version: 0.1.0b</h2>
|
||||
</div>
|
||||
<p>
|
||||
Open: Opens or creates a new document.<br />
|
||||
Save: Saves the current document.<br />
|
||||
Copy: Copies selected text to the clipboard.<br />
|
||||
Paste: Pastes the text in the clipboard to where the cursor is (requires clipboard access).
|
||||
</p>
|
||||
<center><input type="button" onclick="CloseAbout()" value="Close" /></center>
|
||||
<p>
|
||||
|
||||
</div>
|
||||
<textarea id="inputbox" name="text" rows="23" cols="90"></textarea>
|
||||
<p id="writingto"></p>
|
||||
</body>
|
||||
</html>
|
6
apps/Notepad/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Notepad
|
||||
Author: Innovation Inc.
|
||||
Width: 700
|
||||
Height: 450
|
||||
Icon: notepad.png
|
||||
Categpry: /Tools
|
BIN
apps/Notepad/notepad.png
Normal file
After Width: | Height: | Size: 94 KiB |
27
apps/Notepad/php_errors.log
Normal file
|
@ -0,0 +1,27 @@
|
|||
[25-Aug-2020 21:42:10 America/Chicago] PHP Notice: Undefined variable: file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 76
|
||||
[25-Aug-2020 21:42:10 America/Chicago] PHP Notice: Undefined variable: file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 80
|
||||
[25-Aug-2020 21:42:18 America/Chicago] PHP Notice: Undefined variable: file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 76
|
||||
[25-Aug-2020 21:42:18 America/Chicago] PHP Notice: Undefined variable: file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 80
|
||||
[25-Aug-2020 21:44:42 America/Chicago] PHP Parse error: syntax error, unexpected 'return' (T_RETURN), expecting ';' in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 10
|
||||
[25-Aug-2020 21:50:40 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:12 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:22 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:24 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:32 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:41 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:51:48 America/Chicago] PHP Notice: Undefined index: open in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:52:43 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:52:46 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:52:47 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:53:04 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:53:06 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:53:45 America/Chicago] PHP Parse error: syntax error, unexpected '<', expecting end of file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 213
|
||||
[25-Aug-2020 21:53:47 America/Chicago] PHP Parse error: syntax error, unexpected '<', expecting end of file in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 213
|
||||
[25-Aug-2020 21:53:54 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:53:54 America/Chicago] PHP Notice: Undefined index: action in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 212
|
||||
[25-Aug-2020 21:55:30 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:55:33 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:59:29 America/Chicago] PHP Notice: Undefined index: openfile in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 211
|
||||
[25-Aug-2020 21:59:29 America/Chicago] PHP Notice: Undefined index: action in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 212
|
||||
[26-Aug-2020 08:55:57 America/Chicago] PHP Warning: file_get_contents(/mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/home/user/Documents/NewFile.txt): failed to open stream: No such file or directory in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 11
|
||||
[27-Oct-2020 09:13:28 America/Chicago] PHP Warning: file_get_contents(/mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/home/user/Documents/NewFile.txt): failed to open stream: No such file or directory in /mnt/c/Users/Sam/Documents/dremjs/DremJS-0.1.6b/apps/notepad/index.php on line 11
|
|
@ -20,17 +20,35 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
function GetDremJSMenuFunctions() {
|
||||
return [
|
||||
["Secret", "SecretFunctionLol();"]
|
||||
];
|
||||
}
|
||||
function SecretFunctionLol() {
|
||||
window.location.replace("https://www.youtube.com/embed/fC7oUOUEEi4");
|
||||
}
|
||||
</script>
|
||||
<section class="container">
|
||||
<div class="left">
|
||||
<img src="logo.png" style="width:128px;height:128px" />
|
||||
</div>
|
||||
<div class="right">
|
||||
<h1>About DremJS</h1>
|
||||
<h2>Version: 0.1.6b</h2>
|
||||
<h2>Agenda WM 0.1.1b</h2>
|
||||
<h2>Version: 0.1.7b</h2>
|
||||
<h2>Agenda WM 0.1.2b</h2>
|
||||
</div>
|
||||
</section>
|
||||
<p>Changelog:<br />
|
||||
Version 0.1.7b<br />
|
||||
+File Manager<br />
|
||||
+Notepad<br />
|
||||
+A right-click context menu<br />
|
||||
-Removed ambient music on most applications<br />
|
||||
~General system stability improvements to enhance the user's experience.<br /><br />
|
||||
Version 0.1.6b<br />
|
||||
+Widget support (see wiki for more information)<br />
|
||||
+Made clicking apps in the taskbar move applications to the front instead of minimizing.<br />
|
||||
|
|
6
apps/about/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: About
|
||||
Author: Innovation Inc.
|
||||
Width: 800
|
||||
Height: 500
|
||||
Icon: about.png
|
||||
Category: /
|
|
@ -1 +0,0 @@
|
|||
About
|
|
@ -13,6 +13,9 @@
|
|||
</style>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<embed src="https://sparrdrem.github.io/DremJS/apps/debug/chord.mp3" width="0" height="0" loop="true" autostart="true" hidden="true" />
|
||||
<h1>
|
||||
Notice
|
||||
|
|
6
apps/debug/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Debug
|
||||
Author: Innovation Inc.
|
||||
Width: 700
|
||||
Height: 450
|
||||
Icon: debug.png
|
||||
Category: /Tools
|
|
@ -1 +0,0 @@
|
|||
Debug
|
|
@ -15,7 +15,10 @@
|
|||
}
|
||||
</style>
|
||||
<body>
|
||||
<embed src="ambient.mp3" width="0" height="0" loop="true" autostart="true" hidden="true">
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<!--<embed src="ambient.mp3" width="0" height="0" loop="true" autostart="true" hidden="true">-->
|
||||
<h1>
|
||||
How to Install Applications On DremJS
|
||||
</h1>
|
||||
|
|
6
apps/howto/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: How to Install Applications
|
||||
Author: Innovation Inc.
|
||||
Width: 800
|
||||
Height: 500
|
||||
Icon: howto.png
|
||||
Category: /
|
|
@ -1 +0,0 @@
|
|||
How to Install Applications
|
|
@ -1,5 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<meta http-equiv = "refresh" content = "0; url = https://sparrdrem.github.io/DremJS-Market/" />
|
||||
</head>
|
||||
</html>
|
||||
|
|
6
apps/market/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: DremJS Market
|
||||
Author: Innovation Science
|
||||
Width: max
|
||||
Height: max
|
||||
Icon: market.png
|
||||
Category: /
|
|
@ -1 +0,0 @@
|
|||
DremJS Market
|
|
@ -18,6 +18,9 @@
|
|||
background-color: #D3D3D3;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var i = 0
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener("contextmenu", event => event.preventDefault());
|
||||
</script>
|
||||
<div class="buttons">
|
||||
<button type="button" class="buttonA" disabled>Status</button>
|
||||
<a href="TaskManager.html"><button type="button" class="buttonB">Task Manager</button></a>
|
||||
|
|
6
apps/serverstatus/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Server Status
|
||||
Author: Innovation Science
|
||||
Width: 300
|
||||
Height: 300
|
||||
Icon: serverstatus.png
|
||||
Category: /
|
|
@ -1 +0,0 @@
|
|||
Server Status
|
|
@ -1,6 +1,9 @@
|
|||
<!-- Terminal Forwarder -->
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<meta http-equiv="refresh" content="0;url=../../terminal.html" />
|
||||
</head>
|
||||
</html>
|
6
apps/terminal/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Terminal
|
||||
Author: Innovation Science
|
||||
Width: 700
|
||||
Height: 450
|
||||
Icon: terminal.png
|
||||
Category: /
|
|
@ -1 +0,0 @@
|
|||
Terminal
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<?php
|
||||
echo "List of availible widgets:<br />";
|
||||
$widgets = array_filter(glob(getenv('DOCUMENT_ROOT').'/widgets/*'), 'is_dir');
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<?php
|
||||
echo "List of availible widgets:<br />";
|
||||
$widgets = array_filter(glob(getenv('DOCUMENT_ROOT').'/widgets/*'), 'is_dir');
|
||||
|
|
6
apps/widgets-settings/meta
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Widgets Settings
|
||||
Author: Innovation Science
|
||||
Width: -1
|
||||
Height: -1
|
||||
Icon: widgets-settings.png
|
||||
Category: /Tools
|
|
@ -1 +0,0 @@
|
|||
Widgets Settings
|
|
@ -1 +0,0 @@
|
|||
|
BIN
home/user/Music/song.mp3
Normal file
BIN
home/user/Music/town.mp3
Normal file
499
home/user/index.php
Normal file
|
@ -0,0 +1,499 @@
|
|||
<?php
|
||||
/********************************
|
||||
Simple PHP File Manager
|
||||
Copyright John Campbell (jcampbell1)
|
||||
|
||||
Liscense: MIT
|
||||
********************************/
|
||||
|
||||
// Thanks for providing such a great PHP application!
|
||||
|
||||
//Disable error report for undefined superglobals
|
||||
error_reporting( error_reporting() & ~E_NOTICE );
|
||||
|
||||
//Security options
|
||||
$allow_delete = true; // Set to false to disable delete button and delete POST request.
|
||||
$allow_upload = true; // Set to true to allow upload files
|
||||
$allow_create_folder = true; // Set to false to disable folder creation
|
||||
$allow_direct_link = true; // Set to false to only allow downloads and not direct link
|
||||
$allow_show_folders = true; // Set to false to hide all subdirectories
|
||||
|
||||
$disallowed_patterns = ['*.php']; // must be an array. Matching files not allowed to be uploaded
|
||||
$hidden_patterns = ['*.php','.*']; // Matching files hidden in directory index
|
||||
|
||||
$PASSWORD = ''; // Set the password, to access the file manager... (optional)
|
||||
|
||||
if($PASSWORD) {
|
||||
|
||||
session_start();
|
||||
if(!$_SESSION['_sfm_allowed']) {
|
||||
// sha1, and random bytes to thwart timing attacks. Not meant as secure hashing.
|
||||
$t = bin2hex(openssl_random_pseudo_bytes(10));
|
||||
if($_POST['p'] && sha1($t.$_POST['p']) === sha1($t.$PASSWORD)) {
|
||||
$_SESSION['_sfm_allowed'] = true;
|
||||
header('Location: ?');
|
||||
}
|
||||
echo '<html><body><form action=? method=post>PASSWORD:<input type=password name=p autofocus/></form></body></html>';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// must be in UTF-8 or `basename` doesn't work
|
||||
setlocale(LC_ALL,'en_US.UTF-8');
|
||||
|
||||
$tmp_dir = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||
if(DIRECTORY_SEPARATOR==='\\') $tmp_dir = str_replace('/',DIRECTORY_SEPARATOR,$tmp_dir);
|
||||
$tmp = get_absolute_path($tmp_dir . '/' .$_REQUEST['file']);
|
||||
|
||||
if($tmp === false)
|
||||
err(404,'File or Directory Not Found');
|
||||
if(substr($tmp, 0,strlen($tmp_dir)) !== $tmp_dir)
|
||||
err(403,"Forbidden");
|
||||
if(strpos($_REQUEST['file'], DIRECTORY_SEPARATOR) === 0)
|
||||
err(403,"Forbidden");
|
||||
if(preg_match('@^.+://@',$_REQUEST['file'])) {
|
||||
err(403,"Forbidden");
|
||||
}
|
||||
|
||||
|
||||
if(!$_COOKIE['_sfm_xsrf'])
|
||||
setcookie('_sfm_xsrf',bin2hex(openssl_random_pseudo_bytes(16)));
|
||||
if($_POST) {
|
||||
if($_COOKIE['_sfm_xsrf'] !== $_POST['xsrf'] || !$_POST['xsrf'])
|
||||
err(403,"XSRF Failure");
|
||||
}
|
||||
|
||||
$file = $_REQUEST['file'] ?: '.';
|
||||
|
||||
if($_GET['do'] == 'list') {
|
||||
if (is_dir($file)) {
|
||||
$directory = $file;
|
||||
$result = [];
|
||||
$files = array_diff(scandir($directory), ['.','..']);
|
||||
foreach ($files as $entry) if (!is_entry_ignored($entry, $allow_show_folders, $hidden_patterns)) {
|
||||
$i = $directory . '/' . $entry;
|
||||
$stat = stat($i);
|
||||
$result[] = [
|
||||
'mtime' => $stat['mtime'],
|
||||
'size' => $stat['size'],
|
||||
'name' => basename($i),
|
||||
'path' => preg_replace('@^\./@', '', $i),
|
||||
'is_dir' => is_dir($i),
|
||||
'is_deleteable' => $allow_delete && ((!is_dir($i) && is_writable($directory)) ||
|
||||
(is_dir($i) && is_writable($directory) && is_recursively_deleteable($i))),
|
||||
'is_readable' => is_readable($i),
|
||||
'is_writable' => is_writable($i),
|
||||
'is_executable' => is_executable($i),
|
||||
];
|
||||
}
|
||||
usort($result,function($f1,$f2){
|
||||
$f1_key = ($f1['is_dir']?:2) . $f1['name'];
|
||||
$f2_key = ($f2['is_dir']?:2) . $f2['name'];
|
||||
return $f1_key > $f2_key;
|
||||
});
|
||||
} else {
|
||||
err(412,"Not a Directory");
|
||||
}
|
||||
echo json_encode(['success' => true, 'is_writable' => is_writable($file), 'results' =>$result]);
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'delete') {
|
||||
if($allow_delete) {
|
||||
rmrf($file);
|
||||
}
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'mkdir' && $allow_create_folder) {
|
||||
// don't allow actions outside root. we also filter out slashes to catch args like './../outside'
|
||||
$dir = $_POST['name'];
|
||||
$dir = str_replace('/', '', $dir);
|
||||
if(substr($dir, 0, 2) === '..')
|
||||
exit;
|
||||
chdir($file);
|
||||
@mkdir($_POST['name']);
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'upload' && $allow_upload) {
|
||||
foreach($disallowed_patterns as $pattern)
|
||||
if(fnmatch($pattern, $_FILES['file_data']['name']))
|
||||
err(403,"Files of this type are not allowed.");
|
||||
|
||||
$res = move_uploaded_file($_FILES['file_data']['tmp_name'], $file.'/'.$_FILES['file_data']['name']);
|
||||
exit;
|
||||
} elseif ($_GET['do'] == 'download') {
|
||||
foreach($disallowed_patterns as $pattern)
|
||||
if(fnmatch($pattern, $file))
|
||||
err(403,"Files of this type are not allowed.");
|
||||
|
||||
$filename = basename($file);
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
header('Content-Type: ' . finfo_file($finfo, $file));
|
||||
header('Content-Length: '. filesize($file));
|
||||
header(sprintf('Content-Disposition: attachment; filename=%s',
|
||||
strpos('MSIE',$_SERVER['HTTP_REFERER']) ? rawurlencode($filename) : "\"$filename\"" ));
|
||||
ob_flush();
|
||||
readfile($file);
|
||||
exit;
|
||||
}
|
||||
|
||||
function is_entry_ignored($entry, $allow_show_folders, $hidden_patterns) {
|
||||
if ($entry === basename(__FILE__)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_dir($entry) && !$allow_show_folders) {
|
||||
return true;
|
||||
}
|
||||
foreach($hidden_patterns as $pattern) {
|
||||
if(fnmatch($pattern,$entry)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function rmrf($dir) {
|
||||
if(is_dir($dir)) {
|
||||
$files = array_diff(scandir($dir), ['.','..']);
|
||||
foreach ($files as $file)
|
||||
rmrf("$dir/$file");
|
||||
rmdir($dir);
|
||||
} else {
|
||||
unlink($dir);
|
||||
}
|
||||
}
|
||||
function is_recursively_deleteable($d) {
|
||||
$stack = [$d];
|
||||
while($dir = array_pop($stack)) {
|
||||
if(!is_readable($dir) || !is_writable($dir))
|
||||
return false;
|
||||
$files = array_diff(scandir($dir), ['.','..']);
|
||||
foreach($files as $file) if(is_dir($file)) {
|
||||
$stack[] = "$dir/$file";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// from: http://php.net/manual/en/function.realpath.php#84012
|
||||
function get_absolute_path($path) {
|
||||
$path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
|
||||
$parts = explode(DIRECTORY_SEPARATOR, $path);
|
||||
$absolutes = [];
|
||||
foreach ($parts as $part) {
|
||||
if ('.' == $part) continue;
|
||||
if ('..' == $part) {
|
||||
array_pop($absolutes);
|
||||
} else {
|
||||
$absolutes[] = $part;
|
||||
}
|
||||
}
|
||||
return implode(DIRECTORY_SEPARATOR, $absolutes);
|
||||
}
|
||||
|
||||
function err($code,$msg) {
|
||||
http_response_code($code);
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode(['error' => ['code'=>intval($code), 'msg' => $msg]]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function asBytes($ini_v) {
|
||||
$ini_v = trim($ini_v);
|
||||
$s = ['g'=> 1<<30, 'm' => 1<<20, 'k' => 1<<10];
|
||||
return intval($ini_v) * ($s[strtolower(substr($ini_v,-1))] ?: 1);
|
||||
}
|
||||
$MAX_UPLOAD_SIZE = min(asBytes(ini_get('post_max_size')), asBytes(ini_get('upload_max_filesize')));
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
|
||||
<style>
|
||||
body {font-family: "lucida grande","Segoe UI",Arial, sans-serif; font-size: 14px;width:1024;padding:1em;margin:0;}
|
||||
th {font-weight: normal; color: #1F75CC; background-color: #F0F9FF; padding:.5em 1em .5em .2em;
|
||||
text-align: left;cursor:pointer;user-select: none;}
|
||||
th .indicator {margin-left: 6px }
|
||||
thead {border-top: 1px solid #82CFFA; border-bottom: 1px solid #96C4EA;border-left: 1px solid #E7F2FB;
|
||||
border-right: 1px solid #E7F2FB; }
|
||||
#top {height:52px;}
|
||||
#mkdir {display:inline-block;float:right;padding-top:16px;}
|
||||
label { display:block; font-size:11px; color:#555;}
|
||||
#file_drop_target {width:500px; padding:12px 0; border: 4px dashed #ccc;font-size:12px;color:#ccc;
|
||||
text-align: center;float:right;margin-right:20px;}
|
||||
#file_drop_target.drag_over {border: 4px dashed #96C4EA; color: #96C4EA;}
|
||||
#upload_progress {padding: 4px 0;}
|
||||
#upload_progress .error {color:#a00;}
|
||||
#upload_progress > div { padding:3px 0;}
|
||||
.no_write #mkdir, .no_write #file_drop_target {display: none}
|
||||
.progress_track {display:inline-block;width:200px;height:10px;border:1px solid #333;margin: 0 4px 0 10px;}
|
||||
.progress {background-color: #82CFFA;height:10px; }
|
||||
footer {font-size:11px; color:#bbbbc5; padding:4em 0 0;text-align: left;}
|
||||
footer a, footer a:visited {color:#bbbbc5;}
|
||||
#breadcrumb { padding-top:34px; font-size:15px; color:#aaa;display:inline-block;float:left;}
|
||||
#folder_actions {width: 50%;float:right;}
|
||||
a, a:visited { color:#00c; text-decoration: none}
|
||||
a:hover {text-decoration: underline}
|
||||
.sort_hide{ display:none;}
|
||||
table {border-collapse: collapse;width:100%;}
|
||||
thead {max-width: 1024px}
|
||||
td { padding:.2em 1em .2em .2em; border-bottom:1px solid #def;height:30px; font-size:12px;white-space: nowrap;}
|
||||
td.first {font-size:14px;white-space: normal;}
|
||||
td.empty { color:#777; font-style: italic; text-align: center;padding:3em 0;}
|
||||
.is_dir .size {color:transparent;font-size:0;}
|
||||
.is_dir .size:before {content: "--"; font-size:14px;color:#333;}
|
||||
.is_dir .download{visibility: hidden}
|
||||
a.delete {display:inline-block;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADtSURBVHjajFC7DkFREJy9iXg0t+EHRKJDJSqRuIVaJT7AF+jR+xuNRiJyS8WlRaHWeOU+kBy7eyKhs8lkJrOzZ3OWzMAD15gxYhB+yzAm0ndez+eYMYLngdkIf2vpSYbCfsNkOx07n8kgWa1UpptNII5VR/M56Nyt6Qq33bbhQsHy6aR0WSyEyEmiCG6vR2ffB65X4HCwYC2e9CTjJGGok4/7Hcjl+ImLBWv1uCRDu3peV5eGQ2C5/P1zq4X9dGpXP+LYhmYz4HbDMQgUosWTnmQoKKf0htVKBZvtFsx6S9bm48ktaV3EXwd/CzAAVjt+gHT5me0AAAAASUVORK5CYII=) no-repeat scroll 0 2px;
|
||||
color:#d00; margin-left: 15px;font-size:11px;padding:0 0 0 13px;
|
||||
}
|
||||
.name {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABAklEQVRIie2UMW6DMBSG/4cYkJClIhauwMgx8CnSC9EjJKcwd2HGYmAwEoMREtClEJxYakmcoWq/yX623veebZmWZcFKWZbXyTHeOeeXfWDN69/uzPP8x1mVUmiaBlLKsxACAC6cc2OPd7zYK1EUYRgGZFkG3/fPAE5fIjcCAJimCXEcGxKnAiICERkSIcQmeVoQhiHatoWUEkopJEkCAB/r+t0lHyVN023c9z201qiq6s2ZYA9jDIwx1HW9xZ4+Ihta69cK9vwLvsX6ivYf4FGIyJj/rg5uqwccd2Ar7OUdOL/kPyKY5/mhZJ53/2asgiAIHhLYMARd16EoCozj6EzwCYrrX5dC9FQIAAAAAElFTkSuQmCC) no-repeat scroll 0px 12px;
|
||||
padding:15px 0 10px 40px;
|
||||
}
|
||||
.is_dir .name {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADdgAAA3YBfdWCzAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAI0SURBVFiF7Vctb1RRED1nZu5977VQVBEQBKZ1GCDBEwy+ISgCBsMPwOH4CUXgsKQOAxq5CaKChEBqShNK222327f79n0MgpRQ2qC2twKOGjE352TO3Jl76e44S8iZsgOww+Dhi/V3nePOsQRFv679/qsnV96ehgAeWvBged3vXi+OJewMW/Q+T8YCLr18fPnNqQq4fS0/MWlQdviwVqNpp9Mvs7l8Wn50aRH4zQIAqOruxANZAG4thKmQA8D7j5OFw/iIgLXvo6mR/B36K+LNp71vVd1cTMR8BFmwTesc88/uLQ5FKO4+k4aarbuPnq98mbdo2q70hmU0VREkEeCOtqrbMprmFqM1psoYAsg0U9EBtB0YozUWzWpVZQgBxMm3YPoCiLpxRrPaYrBKRSUL5qn2AgFU0koMVlkMOo6G2SIymQCAGE/AGHRsWbCRKc8VmaBN4wBIwkZkFmxkWZDSFCwyommZSABgCmZBSsuiHahA8kA2iZYzSapAsmgHlgfdVyGLTFg3iZqQhAqZB923GGUgQhYRVElmAUXIGGVgedQ9AJJnAkqyClCEkkfdM1Pt13VHdxDpnof0jgxB+mYqO5PaCSDRIAbgDgdpKjtmwm13irsnq4ATdKeYcNvUZAt0dg5NVwEQFKrJlpn45lwh/LpbWdela4K5QsXEN61tytWr81l5YSY/n4wdQH84qjd2J6vEz+W0BOAGgLlE/AMAPQCv6e4gmWYC/QF3d/7zf8P/An4AWL/T1+B2nyIAAAAASUVORK5CYII=) no-repeat scroll 0px 10px;
|
||||
padding:15px 0 10px 40px;
|
||||
}
|
||||
.download {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB2klEQVR4nJ2ST2sTQRiHn5mdmj92t9XmUJIWJGq9NHrRgxQiCtqbl97FqxgaL34CP0FD8Qv07EHEU0Ew6EXEk6ci8Q9JtcXEkHR3k+zujIdUqMkmiANzmJdnHn7vzCuIWbe291tSkvhz1pr+q1L2bBwrRgvFrcZKKinfP9zI2EoKmm7Azstf3V7fXK2Wc3ujvIqzAhglwRJoS2ImQZMEBjgyoDS4hv8QGHA1WICvp9yelsA7ITBTIkwWhGBZ0Iv+MUF+c/cB8PTHt08snb+AGAACZDj8qIN6bSe/uWsBb2qV24/GBLn8yl0plY9AJ9NKeL5ICyEIQkkiZenF5XwBDAZzWItLIIR6LGfk26VVxzltJ2gFw2a0FmQLZ+bcbo/DPbcd+PrDyRb+GqRipbGlZtX92UvzjmUpEGC0JgpC3M9dL+qGz16XsvcmCgCK2/vPtTNzJ1x2kkZIRBSivh8Z2Q4+VkvZy6O8HHvWyGyITvA1qndNpxfguQNkc2CIzM0xNk5QLedCEZm1VKsf2XrAXMNrA2vVcq4ZJ4DhvCSAeSALXASuLBTW129U6oPrT969AK4Bq0AeWARs4BRgieMUEkgDmeO9ANipzDnH//nFB0KgAxwATaAFeID5DQNatLGdaXOWAAAAAElFTkSuQmCC) no-repeat scroll 0px 5px;
|
||||
padding:4px 0 4px 20px;
|
||||
}
|
||||
</style>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<script>
|
||||
(function($){
|
||||
$.fn.tablesorter = function() {
|
||||
var $table = this;
|
||||
this.find('th').click(function() {
|
||||
var idx = $(this).index();
|
||||
var direction = $(this).hasClass('sort_asc');
|
||||
$table.tablesortby(idx,direction);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
$.fn.tablesortby = function(idx,direction) {
|
||||
var $rows = this.find('tbody tr');
|
||||
function elementToVal(a) {
|
||||
var $a_elem = $(a).find('td:nth-child('+(idx+1)+')');
|
||||
var a_val = $a_elem.attr('data-sort') || $a_elem.text();
|
||||
return (a_val == parseInt(a_val) ? parseInt(a_val) : a_val);
|
||||
}
|
||||
$rows.sort(function(a,b){
|
||||
var a_val = elementToVal(a), b_val = elementToVal(b);
|
||||
return (a_val > b_val ? 1 : (a_val == b_val ? 0 : -1)) * (direction ? 1 : -1);
|
||||
})
|
||||
this.find('th').removeClass('sort_asc sort_desc');
|
||||
$(this).find('thead th:nth-child('+(idx+1)+')').addClass(direction ? 'sort_desc' : 'sort_asc');
|
||||
for(var i =0;i<$rows.length;i++)
|
||||
this.append($rows[i]);
|
||||
this.settablesortmarkers();
|
||||
return this;
|
||||
}
|
||||
$.fn.retablesort = function() {
|
||||
var $e = this.find('thead th.sort_asc, thead th.sort_desc');
|
||||
if($e.length)
|
||||
this.tablesortby($e.index(), $e.hasClass('sort_desc') );
|
||||
|
||||
return this;
|
||||
}
|
||||
$.fn.settablesortmarkers = function() {
|
||||
this.find('thead th span.indicator').remove();
|
||||
this.find('thead th.sort_asc').append('<span class="indicator">↓<span>');
|
||||
this.find('thead th.sort_desc').append('<span class="indicator">↑<span>');
|
||||
return this;
|
||||
}
|
||||
})(jQuery);
|
||||
$(function(){
|
||||
var XSRF = (document.cookie.match('(^|; )_sfm_xsrf=([^;]*)')||0)[2];
|
||||
var MAX_UPLOAD_SIZE = <?php echo $MAX_UPLOAD_SIZE ?>;
|
||||
var $tbody = $('#list');
|
||||
$(window).on('hashchange',list).trigger('hashchange');
|
||||
$('#table').tablesorter();
|
||||
|
||||
$('#table').on('click','.delete',function(data) {
|
||||
$.post("",{'do':'delete',file:$(this).attr('data-file'),xsrf:XSRF},function(response){
|
||||
list();
|
||||
},'json');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#mkdir').submit(function(e) {
|
||||
var hashval = decodeURIComponent(window.location.hash.substr(1)),
|
||||
$dir = $(this).find('[name=name]');
|
||||
e.preventDefault();
|
||||
$dir.val().length && $.post('?',{'do':'mkdir',name:$dir.val(),xsrf:XSRF,file:hashval},function(data){
|
||||
list();
|
||||
},'json');
|
||||
$dir.val('');
|
||||
return false;
|
||||
});
|
||||
<?php if($allow_upload): ?>
|
||||
// file upload stuff
|
||||
$('#file_drop_target').on('dragover',function(){
|
||||
$(this).addClass('drag_over');
|
||||
return false;
|
||||
}).on('dragend',function(){
|
||||
$(this).removeClass('drag_over');
|
||||
return false;
|
||||
}).on('drop',function(e){
|
||||
e.preventDefault();
|
||||
var files = e.originalEvent.dataTransfer.files;
|
||||
$.each(files,function(k,file) {
|
||||
uploadFile(file);
|
||||
});
|
||||
$(this).removeClass('drag_over');
|
||||
});
|
||||
$('input[type=file]').change(function(e) {
|
||||
e.preventDefault();
|
||||
$.each(this.files,function(k,file) {
|
||||
uploadFile(file);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function uploadFile(file) {
|
||||
var folder = decodeURIComponent(window.location.hash.substr(1));
|
||||
|
||||
if(file.size > MAX_UPLOAD_SIZE) {
|
||||
var $error_row = renderFileSizeErrorRow(file,folder);
|
||||
$('#upload_progress').append($error_row);
|
||||
window.setTimeout(function(){$error_row.fadeOut();},5000);
|
||||
return false;
|
||||
}
|
||||
|
||||
var $row = renderFileUploadRow(file,folder);
|
||||
$('#upload_progress').append($row);
|
||||
var fd = new FormData();
|
||||
fd.append('file_data',file);
|
||||
fd.append('file',folder);
|
||||
fd.append('xsrf',XSRF);
|
||||
fd.append('do','upload');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', '?');
|
||||
xhr.onload = function() {
|
||||
$row.remove();
|
||||
list();
|
||||
};
|
||||
xhr.upload.onprogress = function(e){
|
||||
if(e.lengthComputable) {
|
||||
$row.find('.progress').css('width',(e.loaded/e.total*100 | 0)+'%' );
|
||||
}
|
||||
};
|
||||
xhr.send(fd);
|
||||
}
|
||||
function renderFileUploadRow(file,folder) {
|
||||
return $row = $('<div/>')
|
||||
.append( $('<span class="fileuploadname" />').text( (folder ? folder+'/':'')+file.name))
|
||||
.append( $('<div class="progress_track"><div class="progress"></div></div>') )
|
||||
.append( $('<span class="size" />').text(formatFileSize(file.size)) )
|
||||
};
|
||||
function renderFileSizeErrorRow(file,folder) {
|
||||
return $row = $('<div class="error" />')
|
||||
.append( $('<span class="fileuploadname" />').text( 'Error: ' + (folder ? folder+'/':'')+file.name))
|
||||
.append( $('<span/>').html(' file size - <b>' + formatFileSize(file.size) + '</b>'
|
||||
+' exceeds max upload size of <b>' + formatFileSize(MAX_UPLOAD_SIZE) + '</b>') );
|
||||
}
|
||||
<?php endif; ?>
|
||||
function list() {
|
||||
var hashval = window.location.hash.substr(1);
|
||||
$.get('?do=list&file='+ hashval,function(data) {
|
||||
$tbody.empty();
|
||||
$('#breadcrumb').empty().html(renderBreadcrumbs(hashval));
|
||||
if(data.success) {
|
||||
$.each(data.results,function(k,v){
|
||||
$tbody.append(renderFileRow(v));
|
||||
});
|
||||
!data.results.length && $tbody.append('<tr><td class="empty" colspan=5>This folder is empty</td></tr>')
|
||||
data.is_writable ? $('body').removeClass('no_write') : $('body').addClass('no_write');
|
||||
} else {
|
||||
console.warn(data.error.msg);
|
||||
}
|
||||
$('#table').retablesort();
|
||||
},'json');
|
||||
}
|
||||
function renderFileRow(data) {
|
||||
var $link = $('<a class="name" />')
|
||||
.attr('href', data.is_dir ? '#' + encodeURIComponent(data.path) : './' + data.path)
|
||||
.text(data.name);
|
||||
var allow_direct_link = <?php echo $allow_direct_link?'true':'false'; ?>;
|
||||
if (!data.is_dir && !allow_direct_link) $link.css('pointer-events','none');
|
||||
var $dl_link = $('<a/>').attr('href','?do=download&file='+ encodeURIComponent(data.path))
|
||||
.addClass('download').text('download');
|
||||
var $delete_link = $('<a href="#" />').attr('data-file',data.path).addClass('delete').text('delete');
|
||||
var perms = [];
|
||||
if(data.is_readable) perms.push('read');
|
||||
if(data.is_writable) perms.push('write');
|
||||
if(data.is_executable) perms.push('exec');
|
||||
var $html = $('<tr />')
|
||||
.addClass(data.is_dir ? 'is_dir' : '')
|
||||
.append( $('<td class="first" />').append($link) )
|
||||
.append( $('<td/>').attr('data-sort',data.is_dir ? -1 : data.size)
|
||||
.html($('<span class="size" />').text(formatFileSize(data.size))) )
|
||||
.append( $('<td/>').attr('data-sort',data.mtime).text(formatTimestamp(data.mtime)) )
|
||||
.append( $('<td/>').text(perms.join('+')) )
|
||||
.append( $('<td/>').append($dl_link).append( data.is_deleteable ? $delete_link : '') )
|
||||
return $html;
|
||||
}
|
||||
function renderBreadcrumbs(path) {
|
||||
var base = "",
|
||||
$html = $('<div/>').append( $('<a href=#>Home</a></div>') );
|
||||
$.each(path.split('%2F'),function(k,v){
|
||||
if(v) {
|
||||
var v_as_text = decodeURIComponent(v);
|
||||
$html.append( $('<span/>').text(' ▸ ') )
|
||||
.append( $('<a/>').attr('href','#'+base+v).text(v_as_text) );
|
||||
base += v + '%2F';
|
||||
}
|
||||
});
|
||||
return $html;
|
||||
}
|
||||
function formatTimestamp(unix_timestamp) {
|
||||
var m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
var d = new Date(unix_timestamp*1000);
|
||||
return [m[d.getMonth()],' ',d.getDate(),', ',d.getFullYear()," ",
|
||||
(d.getHours() % 12 || 12),":",(d.getMinutes() < 10 ? '0' : '')+d.getMinutes(),
|
||||
" ",d.getHours() >= 12 ? 'PM' : 'AM'].join('');
|
||||
}
|
||||
function formatFileSize(bytes) {
|
||||
var s = ['bytes', 'KB','MB','GB','TB','PB','EB'];
|
||||
for(var pos = 0;bytes >= 1000; pos++,bytes /= 1024);
|
||||
var d = Math.round(bytes*10);
|
||||
return pos ? [parseInt(d/10),".",d%10," ",s[pos]].join('') : bytes + ' bytes';
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
</head><body>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<div id="top">
|
||||
<?php if($allow_create_folder): ?>
|
||||
<form action="?" method="post" id="mkdir" />
|
||||
<label for=dirname>Create New Folder</label><input id=dirname type=text name=name value="" />
|
||||
<input type="submit" value="create" />
|
||||
</form>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($allow_upload): ?>
|
||||
|
||||
<div id="file_drop_target">
|
||||
Drag Files Here To Upload
|
||||
<b>or</b>
|
||||
<input type="file" multiple />
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="breadcrumb"> </div>
|
||||
</div>
|
||||
|
||||
<div id="upload_progress"></div>
|
||||
<table id="table"><thead><tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Modified</th>
|
||||
<th>Permissions</th>
|
||||
<th>Actions</th>
|
||||
</tr></thead><tbody id="list">
|
||||
|
||||
</tbody></table>
|
||||
<footer><a href="/rootfb.php">Index of <?php echo preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__); ?> | Press to unlock root on this browser</a></footer>
|
||||
</body></html>
|
151
index.html
|
@ -1,151 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/base/jquery-ui.css"/>
|
||||
<!-- classes were from SparrOS Developer Team -->
|
||||
<title>DremJS</title>
|
||||
<style>
|
||||
.framewrap {
|
||||
width:500px;
|
||||
height:300px;
|
||||
padding:10px;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 10px;
|
||||
background-color:#87CEEB;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
.appFrame {
|
||||
width:99%;
|
||||
height:93%;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
.cwhite {
|
||||
color: white;
|
||||
}
|
||||
.br1 {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.br2 {
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.br3 {
|
||||
position: absolute;
|
||||
bottom: 36px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
html {
|
||||
background: url(DremJS-Background.png) no-repeat center center fixed;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
body {
|
||||
font-family: Calibri;
|
||||
}
|
||||
a:link {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
.cent {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
.taskbar {
|
||||
background-color: black;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
/*z-index: 20000;*/
|
||||
}
|
||||
.taskbarTime {
|
||||
height: 42px;
|
||||
float: left;
|
||||
}
|
||||
.taskbarApps {
|
||||
text-align: center;
|
||||
float: left;
|
||||
margin-left: 5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.startbtn {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
padding: 8px; // Bad way of doing this but that's a problem for future Sam
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
z-index: 30000;
|
||||
}
|
||||
.start-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right:0px;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 200px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
padding: 12px 16px;
|
||||
z-index: 30000;
|
||||
}
|
||||
.start {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top:0px;
|
||||
right:0px;
|
||||
z-index:30000;
|
||||
}
|
||||
.start-content a:hover {background-color: #ccc}
|
||||
.start:hover .start-content {
|
||||
display: block;
|
||||
}
|
||||
.start:hover .startbtn {
|
||||
background-color: gray;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="initAgendaWM()">
|
||||
<p class="cwhite br2">DremJS Version 0.1.6b</p>
|
||||
<p class="cwhite br1">© Innovation Inc.</p>
|
||||
|
||||
<div class="start">
|
||||
<button class="startbtn"><img src="logo.png" style="width:24px;height24px;"></button>
|
||||
<div class="start-content">
|
||||
<a onclick="openApplication('about', 800, 500, 'about.png')"><p><img src="apps/about/about.png" align="top"> About DremJS</p></a>
|
||||
<a onclick="openApplication('howto', 800, 500, 'howto.png')"><p><img src="apps/howto/howto.png" align="top"> How to Install Applications</p></a>
|
||||
<a onclick="openApplication('market', 'max', 'max', 'market.png')"><p><img src="apps/market/market.png" align="top"> DremJS Market</p></a>
|
||||
<a onclick="openApplication('debug', 700, 450, 'debug.png')"><p><img src="apps/debug/debug.png" align="top"> Report a Bug</p></a>
|
||||
<a onclick="openApplication('terminal', 700, 450, 'terminal.png')"><p><img src="apps/terminal/terminal.png" align="top" width="16" height="16"> Terminal</p></a>
|
||||
<a onclick="openApplication('serverstatus', '300', '300', 'serverstatus.png')"><p><img src="apps/serverstatus/serverstatus.png" align="top" style="width:16px;height:16px;"> Server Status</p></a>
|
||||
<a onclick="openApplication('widgets-settings', -1, -1, 'widgets-settings.png')"><p><img src="apps/widgets-settings/widgets-settings.png" align="top" style="width:16px;height:16px"> Widgets Settings</p></a>
|
||||
<hr />
|
||||
<a target="_top" href="shuttingdown.html"><p><img src="shutdown.png" align="top" style="width:16px;height:16px;"> Shutdown DremJS</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="appContainer">
|
||||
<!-- This is the taskbar -->
|
||||
<div id="taskbar" class="taskbar">
|
||||
<div id="taskbarTime" class="taskbarTime">
|
||||
<!-- Add apps here -->
|
||||
<div class="cwhite" style="text-align:left" id="txt"></div> <a onclick="openApplication('about', 800, 500, 'about.png')"><img src="apps/about/about.png"> |</a>
|
||||
</div>
|
||||
<div id="taskbarApps" class="taskbarApps">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="agenda-wm.js"></script>
|
||||
</body>
|
||||
</html>
|
406
index.php
Normal file
|
@ -0,0 +1,406 @@
|
|||
<html>
|
||||
<head>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||
<script src="jquery.ui.touch-punch.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/base/jquery-ui.css"/>
|
||||
<!-- classes were from SparrOS Developer Team -->
|
||||
<title>DremJS</title>
|
||||
<style>
|
||||
.framewrap {
|
||||
width:500px;
|
||||
height:300px;
|
||||
padding:10px;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 10px;
|
||||
background-color:#87CEEB;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
.framewrapMobile {
|
||||
width:100%;
|
||||
height:100%;
|
||||
/*padding:10px;*/
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 0px;
|
||||
background-color:#87CEEB;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
.appFrame {
|
||||
width:99%;
|
||||
height:93%;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
.appFrameMobile {
|
||||
width:99%;
|
||||
height:99%;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
.cwhite {
|
||||
color: white;
|
||||
}
|
||||
.br1 {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.br2 {
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.br3 {
|
||||
position: absolute;
|
||||
bottom: 36px;
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
html {
|
||||
background: url(DremJS-Background.png) no-repeat center center fixed;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
body {
|
||||
font-family: Calibri;
|
||||
margin:0px;
|
||||
}
|
||||
a:link {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
.cent {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
}
|
||||
.taskbar {
|
||||
background-color: black;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
/*z-index: 20000;*/
|
||||
}
|
||||
.taskbarTime {
|
||||
height: 42px;
|
||||
float: left;
|
||||
}
|
||||
.taskbarApps {
|
||||
text-align: center;
|
||||
float: left;
|
||||
margin-left: 5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.startbtn {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
padding: 8px; // Bad way of doing this but that's a problem for future Sam
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
z-index: 30000;
|
||||
}
|
||||
.start-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right:0px;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 200px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
padding: 12px 16px;
|
||||
z-index: 30000;
|
||||
}
|
||||
.start {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top:0px;
|
||||
right:0px;
|
||||
z-index:30000;
|
||||
}
|
||||
.start-content a:hover {background-color: #ccc}
|
||||
.start:hover .start-content {
|
||||
display: block;
|
||||
}
|
||||
.start:hover .startbtn {
|
||||
background-color: gray;
|
||||
}
|
||||
#context-menu {
|
||||
position:fixed;
|
||||
z-index:30000;
|
||||
width:150px;
|
||||
background:#1b1a1a;
|
||||
/*border-radius:5px;*/
|
||||
transform:scale(0);
|
||||
transform-origin:top left;
|
||||
}
|
||||
#context-menu.active {
|
||||
transform:scale(1);
|
||||
transition:transform 300ms ease-in-out;
|
||||
}
|
||||
#context-menu .item {
|
||||
padding:8px 10px;
|
||||
font-size:15px;
|
||||
color:#eee;
|
||||
}
|
||||
#context-menu .item:hover {
|
||||
background:#555;
|
||||
}
|
||||
#context-menu .item i {
|
||||
display:inline-block;
|
||||
margin-right:5px;
|
||||
}
|
||||
#context-menu hr {
|
||||
margin:2px 0px;
|
||||
border-color:#555;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="initAgendaWM(); touchstart();">
|
||||
<div id="main" tabindex="-1">
|
||||
<p class="cwhite br2">DremJS Version 0.1.7b</p>
|
||||
<p class="cwhite br1">© Innovation Inc.</p>
|
||||
<div id="context-menu">
|
||||
|
||||
</div>
|
||||
<div class="start">
|
||||
<button class="startbtn"><img src="logo.png" style="width:24px;height24px;"></button>
|
||||
<div class="start-content">
|
||||
<a onclick="openApplication('about', 800, 500, 'about.png')"><p><img src="apps/about/about.png" align="top"> About DremJS</p></a>
|
||||
<a onclick="openApplication('howto', 800, 500, 'howto.png')"><p><img src="apps/howto/howto.png" align="top"> How to Install Applications</p></a>
|
||||
<a onclick="openApplication('market', 'max', 'max', 'market.png')"><p><img src="apps/market/market.png" align="top"> DremJS Market</p></a>
|
||||
<a onclick="openApplication('debug', 700, 450, 'debug.png')"><p><img src="apps/debug/debug.png" align="top"> Report a Bug</p></a>
|
||||
<a onclick="openApplication('FileManager', 700, 450, 'filemanager.png')"><p><img src="apps/FileManager/filemanager.png" align="top" width="16" height="16"> File Manager</p></a>
|
||||
<a onclick="openApplication('Cinema', 700, 450, 'cinema.png')"><p><img src="apps/Cinema/cinema.png" align="top" width="16" height="16"> Cinema</p></a>
|
||||
<a onclick="openApplication('Notepad', 700, 450, 'notepad.png')"><p><img src="apps/Notepad/notepad.png" align="top" width="16" height="16"> Notepad</p></a>
|
||||
<a onclick="openApplication('terminal', 700, 450, 'terminal.png')"><p><img src="apps/terminal/terminal.png" align="top" width="16" height="16"> Terminal</p></a>
|
||||
<a onclick="openApplication('serverstatus', '300', '300', 'serverstatus.png')"><p><img src="apps/serverstatus/serverstatus.png" align="top" style="width:16px;height:16px;"> Server Status</p></a>
|
||||
<a onclick="openApplication('widgets-settings', -1, -1, 'widgets-settings.png')"><p><img src="apps/widgets-settings/widgets-settings.png" align="top" style="width:16px;height:16px"> Widgets Settings</p></a>
|
||||
<hr />
|
||||
<a target="_top" href="shuttingdown.html"><p><img src="shutdown.png" align="top" style="width:16px;height:16px;"> Shutdown DremJS</p></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="appContainer">
|
||||
<!-- This is the taskbar -->
|
||||
<div id="taskbar" class="taskbar">
|
||||
<div id="taskbarTime" class="taskbarTime">
|
||||
<!-- Add apps here -->
|
||||
<div class="cwhite" style="text-align:left" id="txt"></div> <a onclick="openApplication('about', 800, 500, 'about.png')"><img src="apps/about/about.png"> |</a>
|
||||
</div>
|
||||
<div id="taskbarApps" class="taskbarApps">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="mobile-detect.js"></script>
|
||||
<script src="agenda-wm.js"></script>
|
||||
<script>
|
||||
var counter;
|
||||
var pressHoldDuration = 50;
|
||||
var pressHoldEvent = new CustomEvent("pressHold");
|
||||
var timerID;
|
||||
//var currentSelectedTaskbarApp = "";
|
||||
var allowContextMenuFlag = true;
|
||||
var firstTouchFlag = false;
|
||||
|
||||
$("#context-menu").hover(function() {
|
||||
allowContextMenuFlag = false;
|
||||
}, function() {
|
||||
allowContextMenuFlag = true;
|
||||
})
|
||||
window.addEventListener("contextmenu",function(event){
|
||||
event.preventDefault();
|
||||
});
|
||||
window.onmousedown = function(eventData) {
|
||||
if (eventData.button === 2) {
|
||||
showContextMenu();
|
||||
}
|
||||
}
|
||||
window.addEventListener("click",function(){
|
||||
closeContextMenu();
|
||||
});
|
||||
function showContextMenu(appid) {
|
||||
if(allowContextMenuFlag == false) { return; }
|
||||
// Base context menu
|
||||
var contextMenuItems = '<!-- DremJS Global Functions -->'
|
||||
/*<div onclick="" class="item">\
|
||||
<i class="fa"></i> Item\
|
||||
</div>*/
|
||||
if(!detector.mobile()) {
|
||||
contextMenuItems+='<div onclick="minimizeAllApplications();" class="item">\
|
||||
<i class="fa"></i> Show Desktop\
|
||||
</div>'
|
||||
}
|
||||
contextMenuItems+='</hr>\
|
||||
<!-- Application-Specific Functions -->\
|
||||
\
|
||||
'
|
||||
if(GetCurrentTaskbarApp() != "") {
|
||||
contextMenuItems+='<div onclick="closeApplication(' + GetCurrentTaskbarApp() + ')" class="item">\
|
||||
<i class="fa"></i> Close Application\
|
||||
</div>';
|
||||
} else if($(":focus").attr('class') == "taskbarApps") {
|
||||
contextMenuItems+='<div onclick="closeApplication(' + $(":focus").attr('id').substr(4, $(":focus").attr('id').length) + ')" class="item">\
|
||||
<i class="fa"></i> Close Application\
|
||||
</div>';
|
||||
}
|
||||
SetCurrentTaskbarApp("");
|
||||
// Grab 2D array of elements and corresponding JavaScript functions (should be JSON but I don't know how to JSON)
|
||||
var failedFlag = false;
|
||||
//if(appid) {
|
||||
id=appid;
|
||||
//} else {
|
||||
// var id=$(':focus').attr('id');
|
||||
//}
|
||||
try {
|
||||
var applicationFunctions = document.getElementById(id).contentWindow.GetDremJSMenuFunctions();
|
||||
} catch(e) {
|
||||
//console.log("An error occured trying to get custom context menu functions from the application. This probably means the application hasn't been updated for modern versions of DremJS. No custom context menu items will be displayed.")
|
||||
//console.log(e);
|
||||
failedFlag = true;
|
||||
}
|
||||
if (failedFlag == false) {
|
||||
contextMenuItems+="<hr />"
|
||||
for(i=0; i<applicationFunctions.length; i++) {
|
||||
if(applicationFunctions[i][0] == "<hr />")
|
||||
contextMenuItems+="<hr />";
|
||||
else
|
||||
contextMenuItems+="<div class='item' onclick=\"document.getElementById('" + id + "').contentWindow." + applicationFunctions[i][1] + "\">\n\t<i class='fa'></i> " + applicationFunctions[i][0] +"\n</div>";
|
||||
}
|
||||
//console.log(contextMenuItems);
|
||||
}
|
||||
//console.log(contextMenuItems);
|
||||
var contextElement = document.getElementById("context-menu");
|
||||
contextElement.innerHTML = '';
|
||||
contextElement.insertAdjacentHTML('beforeend', contextMenuItems);
|
||||
//posX = event.clientX;
|
||||
//posY = event.clientY;
|
||||
|
||||
if(!(detector.mobile())) {
|
||||
posX = event.clientX;
|
||||
posY = event.clientY;
|
||||
if(appid || (document.getElementById(id) && document.getElementById(id).tagName == "IFRAME")) {
|
||||
posX = document.getElementById(id).getBoundingClientRect().left + posX;
|
||||
posY = document.getElementById(id).getBoundingClientRect().top + posY;
|
||||
}
|
||||
contextElement.style.top = posY + "px";
|
||||
contextElement.style.left = posX + "px";
|
||||
} else {
|
||||
// This is what we in the business call a bodge
|
||||
if(appid) {
|
||||
contextElement.style.top = document.getElementById(id).getBoundingClientRect().top + "px";
|
||||
contextElement.style.left = document.getElementById(id).getBoundingClientRect().left + "px";
|
||||
} else {
|
||||
contextElement.style.top = clientY + "px";
|
||||
contextElement.style.left = clientX + "px";
|
||||
}
|
||||
|
||||
}
|
||||
setTimeout(function() { contextElement.classList.add("active"); }, 10);
|
||||
}
|
||||
|
||||
function closeContextMenu() {
|
||||
document.getElementById("context-menu").classList.remove("active");
|
||||
}
|
||||
|
||||
function canAccessIFrame(iframe) {
|
||||
var html = null;
|
||||
try {
|
||||
var doc = iframe.contentDocument || iframe.contentWindow.document;
|
||||
html = doc.body.innerHTML;
|
||||
} catch(err){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
var monitor = setInterval(function(){
|
||||
//var elem = document.activeElement;
|
||||
var elem = $(':focus');
|
||||
if(elem && $(elem).prop("tagName") == 'IFRAME' && canAccessIFrame(elem.get(0))){
|
||||
elem.contents().find("body").mousedown(function(event) {
|
||||
switch (event.which) {
|
||||
case 1:
|
||||
//console.log('Left mouse button pressed - ' + elem.attr('name'));
|
||||
closeContextMenu();
|
||||
break;
|
||||
case 2:
|
||||
//console.log('Middle mouse button pressed');
|
||||
break;
|
||||
case 3:
|
||||
//console.log('Right mouse button pressed - ' + elem.attr('id'));
|
||||
showContextMenu(elem.attr('id'));
|
||||
break;
|
||||
default:
|
||||
console.log('You have a strange mouse');
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
|
||||
var clientX;
|
||||
var clientY;
|
||||
var startX;
|
||||
var startY;
|
||||
var currentX;
|
||||
var currentY;
|
||||
|
||||
var onlongtouch;
|
||||
var timer;
|
||||
var touchduration = 800; //length of time we want the user to touch before we do something
|
||||
|
||||
window.addEventListener('touchstart', function(e) {
|
||||
clientX = e.touches[0].clientX;
|
||||
clientY = e.touches[0].clientY;
|
||||
currentX = clientX;
|
||||
currentY = clientY;
|
||||
//DelayBeforeContextMenu = setTimeout(showContextMenu(), touchduration);
|
||||
});
|
||||
|
||||
function touchstart(e) {
|
||||
//e.preventDefault();
|
||||
startX = clientX;
|
||||
startY = clientY;
|
||||
if (!timer) {
|
||||
timer = setTimeout(onlongtouch, touchduration);
|
||||
}
|
||||
}
|
||||
|
||||
function touchend() {
|
||||
//stops short touches from firing the event
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
onlongtouch = function() {
|
||||
timer = null;
|
||||
if(firstTouchFlag && Math.abs(startX - currentX) < 50 && Math.abs(startY - currentY) < 50) {
|
||||
showContextMenu();
|
||||
} else {
|
||||
firstTouchFlag=true;
|
||||
}
|
||||
};
|
||||
|
||||
function updateXY(e) {
|
||||
currentX = e.touches[0].clientX;
|
||||
currentY = e.touches[0].clientY;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
window.addEventListener("touchstart", touchstart, false);
|
||||
window.addEventListener("touchend", touchend, false);
|
||||
window.addEventListener("touchmove", updateXY, true);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
11
jquery.ui.touch-punch.min.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*!
|
||||
* jQuery UI Touch Punch 0.2.3
|
||||
*
|
||||
* Copyright 2011–2014, Dave Furfero
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.mouse.js
|
||||
*/
|
||||
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
|
1004
mobile-detect.js
Normal file
508
rootfb.php
Normal file
|
@ -0,0 +1,508 @@
|
|||
<?php
|
||||
/********************************
|
||||
Simple PHP File Manager
|
||||
Copyright John Campbell (jcampbell1)
|
||||
|
||||
Liscense: MIT
|
||||
********************************/
|
||||
|
||||
// Thanks for providing such a great PHP application!
|
||||
|
||||
//Disable error report for undefined superglobals
|
||||
error_reporting( error_reporting() & ~E_NOTICE );
|
||||
|
||||
//Security options
|
||||
$allow_delete = true; // Set to false to disable delete button and delete POST request.
|
||||
$allow_upload = true; // Set to true to allow upload files
|
||||
$allow_create_folder = true; // Set to false to disable folder creation
|
||||
$allow_direct_link = true; // Set to false to only allow downloads and not direct link
|
||||
$allow_show_folders = true; // Set to false to hide all subdirectories
|
||||
|
||||
$disallowed_patterns = ['*.php']; // must be an array. Matching files not allowed to be uploaded
|
||||
$hidden_patterns = ['*.php','.*']; // Matching files hidden in directory index
|
||||
|
||||
$PASSWORD = 'admin'; // Set the password, to access the file manager... (optional)
|
||||
|
||||
if($PASSWORD) {
|
||||
|
||||
session_start();
|
||||
// Disabled to prevent using cookies to determine if a computer is trusted.
|
||||
if(!$_SESSION['_sfm_allowed']) {
|
||||
// sha1, and random bytes to thwart timing attacks. Not meant as secure hashing.
|
||||
$t = bin2hex(openssl_random_pseudo_bytes(10));
|
||||
if($_POST['p'] && sha1($t.$_POST['p']) === sha1($t.$PASSWORD)) {
|
||||
$_SESSION['_sfm_allowed'] = true;
|
||||
header('Location: ?');
|
||||
}
|
||||
echo '<html><body><form action=? method=post>PASSWORD:<input type=password name=p autofocus/></form></body></html>';
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// must be in UTF-8 or `basename` doesn't work
|
||||
setlocale(LC_ALL,'en_US.UTF-8');
|
||||
|
||||
$tmp_dir = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||
if(DIRECTORY_SEPARATOR==='\\') $tmp_dir = str_replace('/',DIRECTORY_SEPARATOR,$tmp_dir);
|
||||
$tmp = get_absolute_path($tmp_dir . '/' .$_REQUEST['file']);
|
||||
|
||||
if($tmp === false)
|
||||
err(404,'File or Directory Not Found');
|
||||
if(substr($tmp, 0,strlen($tmp_dir)) !== $tmp_dir)
|
||||
err(403,"Forbidden");
|
||||
if(strpos($_REQUEST['file'], DIRECTORY_SEPARATOR) === 0)
|
||||
err(403,"Forbidden");
|
||||
if(preg_match('@^.+://@',$_REQUEST['file'])) {
|
||||
err(403,"Forbidden");
|
||||
}
|
||||
|
||||
|
||||
if(!$_COOKIE['_sfm_xsrf'])
|
||||
setcookie('_sfm_xsrf',bin2hex(openssl_random_pseudo_bytes(16)));
|
||||
if($_POST) {
|
||||
if($_COOKIE['_sfm_xsrf'] !== $_POST['xsrf'] || !$_POST['xsrf'])
|
||||
err(403,"XSRF Failure");
|
||||
}
|
||||
|
||||
$file = $_REQUEST['file'] ?: '.';
|
||||
|
||||
if($_GET['do'] == 'list') {
|
||||
if (is_dir($file)) {
|
||||
$directory = $file;
|
||||
$result = [];
|
||||
$files = array_diff(scandir($directory), ['.','..']);
|
||||
foreach ($files as $entry) if (!is_entry_ignored($entry, $allow_show_folders, $hidden_patterns)) {
|
||||
$i = $directory . '/' . $entry;
|
||||
$stat = stat($i);
|
||||
$result[] = [
|
||||
'mtime' => $stat['mtime'],
|
||||
'size' => $stat['size'],
|
||||
'name' => basename($i),
|
||||
'path' => preg_replace('@^\./@', '', $i),
|
||||
'is_dir' => is_dir($i),
|
||||
'is_deleteable' => $allow_delete && ((!is_dir($i) && is_writable($directory)) ||
|
||||
(is_dir($i) && is_writable($directory) && is_recursively_deleteable($i))),
|
||||
'is_readable' => is_readable($i),
|
||||
'is_writable' => is_writable($i),
|
||||
'is_executable' => is_executable($i),
|
||||
];
|
||||
}
|
||||
usort($result,function($f1,$f2){
|
||||
$f1_key = ($f1['is_dir']?:2) . $f1['name'];
|
||||
$f2_key = ($f2['is_dir']?:2) . $f2['name'];
|
||||
return $f1_key > $f2_key;
|
||||
});
|
||||
} else {
|
||||
err(412,"Not a Directory");
|
||||
}
|
||||
echo json_encode(['success' => true, 'is_writable' => is_writable($file), 'results' =>$result]);
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'delete') {
|
||||
if($allow_delete) {
|
||||
rmrf($file);
|
||||
}
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'mkdir' && $allow_create_folder) {
|
||||
// don't allow actions outside root. we also filter out slashes to catch args like './../outside'
|
||||
$dir = $_POST['name'];
|
||||
$dir = str_replace('/', '', $dir);
|
||||
if(substr($dir, 0, 2) === '..')
|
||||
exit;
|
||||
chdir($file);
|
||||
@mkdir($_POST['name']);
|
||||
exit;
|
||||
} elseif ($_POST['do'] == 'upload' && $allow_upload) {
|
||||
foreach($disallowed_patterns as $pattern)
|
||||
if(fnmatch($pattern, $_FILES['file_data']['name']))
|
||||
err(403,"Files of this type are not allowed.");
|
||||
|
||||
$res = move_uploaded_file($_FILES['file_data']['tmp_name'], $file.'/'.$_FILES['file_data']['name']);
|
||||
exit;
|
||||
} elseif ($_GET['do'] == 'download') {
|
||||
foreach($disallowed_patterns as $pattern)
|
||||
if(fnmatch($pattern, $file))
|
||||
err(403,"Files of this type are not allowed.");
|
||||
|
||||
$filename = basename($file);
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
header('Content-Type: ' . finfo_file($finfo, $file));
|
||||
header('Content-Length: '. filesize($file));
|
||||
header(sprintf('Content-Disposition: attachment; filename=%s',
|
||||
strpos('MSIE',$_SERVER['HTTP_REFERER']) ? rawurlencode($filename) : "\"$filename\"" ));
|
||||
ob_flush();
|
||||
readfile($file);
|
||||
exit;
|
||||
}
|
||||
|
||||
function is_entry_ignored($entry, $allow_show_folders, $hidden_patterns) {
|
||||
if ($entry === basename(__FILE__)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_dir($entry) && !$allow_show_folders) {
|
||||
return true;
|
||||
}
|
||||
foreach($hidden_patterns as $pattern) {
|
||||
if(fnmatch($pattern,$entry)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function rmrf($dir) {
|
||||
if(is_dir($dir)) {
|
||||
$files = array_diff(scandir($dir), ['.','..']);
|
||||
foreach ($files as $file)
|
||||
rmrf("$dir/$file");
|
||||
rmdir($dir);
|
||||
} else {
|
||||
unlink($dir);
|
||||
}
|
||||
}
|
||||
function is_recursively_deleteable($d) {
|
||||
$stack = [$d];
|
||||
while($dir = array_pop($stack)) {
|
||||
if(!is_readable($dir) || !is_writable($dir))
|
||||
return false;
|
||||
$files = array_diff(scandir($dir), ['.','..']);
|
||||
foreach($files as $file) if(is_dir($file)) {
|
||||
$stack[] = "$dir/$file";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// from: http://php.net/manual/en/function.realpath.php#84012
|
||||
function get_absolute_path($path) {
|
||||
$path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
|
||||
$parts = explode(DIRECTORY_SEPARATOR, $path);
|
||||
$absolutes = [];
|
||||
foreach ($parts as $part) {
|
||||
if ('.' == $part) continue;
|
||||
if ('..' == $part) {
|
||||
array_pop($absolutes);
|
||||
} else {
|
||||
$absolutes[] = $part;
|
||||
}
|
||||
}
|
||||
return implode(DIRECTORY_SEPARATOR, $absolutes);
|
||||
}
|
||||
|
||||
function err($code,$msg) {
|
||||
http_response_code($code);
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode(['error' => ['code'=>intval($code), 'msg' => $msg]]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function asBytes($ini_v) {
|
||||
$ini_v = trim($ini_v);
|
||||
$s = ['g'=> 1<<30, 'm' => 1<<20, 'k' => 1<<10];
|
||||
return intval($ini_v) * ($s[strtolower(substr($ini_v,-1))] ?: 1);
|
||||
}
|
||||
$MAX_UPLOAD_SIZE = min(asBytes(ini_get('post_max_size')), asBytes(ini_get('upload_max_filesize')));
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
|
||||
<style>
|
||||
body {font-family: "lucida grande","Segoe UI",Arial, sans-serif; font-size: 14px;width:1024;padding:1em;margin:0;}
|
||||
th {font-weight: normal; color: #1F75CC; background-color: #F0F9FF; padding:.5em 1em .5em .2em;
|
||||
text-align: left;cursor:pointer;user-select: none;}
|
||||
th .indicator {margin-left: 6px }
|
||||
thead {border-top: 1px solid #82CFFA; border-bottom: 1px solid #96C4EA;border-left: 1px solid #E7F2FB;
|
||||
border-right: 1px solid #E7F2FB; }
|
||||
#top {height:52px;}
|
||||
#mkdir {display:inline-block;float:right;padding-top:16px;}
|
||||
label { display:block; font-size:11px; color:#555;}
|
||||
#file_drop_target {width:500px; padding:12px 0; border: 4px dashed #ccc;font-size:12px;color:#ccc;
|
||||
text-align: center;float:right;margin-right:20px;}
|
||||
#file_drop_target.drag_over {border: 4px dashed #96C4EA; color: #96C4EA;}
|
||||
#upload_progress {padding: 4px 0;}
|
||||
#upload_progress .error {color:#a00;}
|
||||
#upload_progress > div { padding:3px 0;}
|
||||
.no_write #mkdir, .no_write #file_drop_target {display: none}
|
||||
.progress_track {display:inline-block;width:200px;height:10px;border:1px solid #333;margin: 0 4px 0 10px;}
|
||||
.progress {background-color: #82CFFA;height:10px; }
|
||||
footer {font-size:11px; color:#bbbbc5; padding:4em 0 0;text-align: left;}
|
||||
footer a, footer a:visited {color:#bbbbc5;}
|
||||
#breadcrumb { padding-top:34px; font-size:15px; color:#aaa;display:inline-block;float:left;}
|
||||
#folder_actions {width: 50%;float:right;}
|
||||
a, a:visited { color:#00c; text-decoration: none}
|
||||
a:hover {text-decoration: underline}
|
||||
.sort_hide{ display:none;}
|
||||
table {border-collapse: collapse;width:100%;}
|
||||
thead {max-width: 1024px}
|
||||
td { padding:.2em 1em .2em .2em; border-bottom:1px solid #def;height:30px; font-size:12px;white-space: nowrap;}
|
||||
td.first {font-size:14px;white-space: normal;}
|
||||
td.empty { color:#777; font-style: italic; text-align: center;padding:3em 0;}
|
||||
.is_dir .size {color:transparent;font-size:0;}
|
||||
.is_dir .size:before {content: "--"; font-size:14px;color:#333;}
|
||||
.is_dir .download{visibility: hidden}
|
||||
a.delete {display:inline-block;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADtSURBVHjajFC7DkFREJy9iXg0t+EHRKJDJSqRuIVaJT7AF+jR+xuNRiJyS8WlRaHWeOU+kBy7eyKhs8lkJrOzZ3OWzMAD15gxYhB+yzAm0ndez+eYMYLngdkIf2vpSYbCfsNkOx07n8kgWa1UpptNII5VR/M56Nyt6Qq33bbhQsHy6aR0WSyEyEmiCG6vR2ffB65X4HCwYC2e9CTjJGGok4/7Hcjl+ImLBWv1uCRDu3peV5eGQ2C5/P1zq4X9dGpXP+LYhmYz4HbDMQgUosWTnmQoKKf0htVKBZvtFsx6S9bm48ktaV3EXwd/CzAAVjt+gHT5me0AAAAASUVORK5CYII=) no-repeat scroll 0 2px;
|
||||
color:#d00; margin-left: 15px;font-size:11px;padding:0 0 0 13px;
|
||||
}
|
||||
.name {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABAklEQVRIie2UMW6DMBSG/4cYkJClIhauwMgx8CnSC9EjJKcwd2HGYmAwEoMREtClEJxYakmcoWq/yX623veebZmWZcFKWZbXyTHeOeeXfWDN69/uzPP8x1mVUmiaBlLKsxACAC6cc2OPd7zYK1EUYRgGZFkG3/fPAE5fIjcCAJimCXEcGxKnAiICERkSIcQmeVoQhiHatoWUEkopJEkCAB/r+t0lHyVN023c9z201qiq6s2ZYA9jDIwx1HW9xZ4+Ihta69cK9vwLvsX6ivYf4FGIyJj/rg5uqwccd2Ar7OUdOL/kPyKY5/mhZJ53/2asgiAIHhLYMARd16EoCozj6EzwCYrrX5dC9FQIAAAAAElFTkSuQmCC) no-repeat scroll 0px 12px;
|
||||
padding:15px 0 10px 40px;
|
||||
}
|
||||
.is_dir .name {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADdgAAA3YBfdWCzAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAI0SURBVFiF7Vctb1RRED1nZu5977VQVBEQBKZ1GCDBEwy+ISgCBsMPwOH4CUXgsKQOAxq5CaKChEBqShNK222327f79n0MgpRQ2qC2twKOGjE352TO3Jl76e44S8iZsgOww+Dhi/V3nePOsQRFv679/qsnV96ehgAeWvBged3vXi+OJewMW/Q+T8YCLr18fPnNqQq4fS0/MWlQdviwVqNpp9Mvs7l8Wn50aRH4zQIAqOruxANZAG4thKmQA8D7j5OFw/iIgLXvo6mR/B36K+LNp71vVd1cTMR8BFmwTesc88/uLQ5FKO4+k4aarbuPnq98mbdo2q70hmU0VREkEeCOtqrbMprmFqM1psoYAsg0U9EBtB0YozUWzWpVZQgBxMm3YPoCiLpxRrPaYrBKRSUL5qn2AgFU0koMVlkMOo6G2SIymQCAGE/AGHRsWbCRKc8VmaBN4wBIwkZkFmxkWZDSFCwyommZSABgCmZBSsuiHahA8kA2iZYzSapAsmgHlgfdVyGLTFg3iZqQhAqZB923GGUgQhYRVElmAUXIGGVgedQ9AJJnAkqyClCEkkfdM1Pt13VHdxDpnof0jgxB+mYqO5PaCSDRIAbgDgdpKjtmwm13irsnq4ATdKeYcNvUZAt0dg5NVwEQFKrJlpn45lwh/LpbWdela4K5QsXEN61tytWr81l5YSY/n4wdQH84qjd2J6vEz+W0BOAGgLlE/AMAPQCv6e4gmWYC/QF3d/7zf8P/An4AWL/T1+B2nyIAAAAASUVORK5CYII=) no-repeat scroll 0px 10px;
|
||||
padding:15px 0 10px 40px;
|
||||
}
|
||||
.download {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB2klEQVR4nJ2ST2sTQRiHn5mdmj92t9XmUJIWJGq9NHrRgxQiCtqbl97FqxgaL34CP0FD8Qv07EHEU0Ew6EXEk6ci8Q9JtcXEkHR3k+zujIdUqMkmiANzmJdnHn7vzCuIWbe291tSkvhz1pr+q1L2bBwrRgvFrcZKKinfP9zI2EoKmm7Azstf3V7fXK2Wc3ujvIqzAhglwRJoS2ImQZMEBjgyoDS4hv8QGHA1WICvp9yelsA7ITBTIkwWhGBZ0Iv+MUF+c/cB8PTHt08snb+AGAACZDj8qIN6bSe/uWsBb2qV24/GBLn8yl0plY9AJ9NKeL5ICyEIQkkiZenF5XwBDAZzWItLIIR6LGfk26VVxzltJ2gFw2a0FmQLZ+bcbo/DPbcd+PrDyRb+GqRipbGlZtX92UvzjmUpEGC0JgpC3M9dL+qGz16XsvcmCgCK2/vPtTNzJ1x2kkZIRBSivh8Z2Q4+VkvZy6O8HHvWyGyITvA1qndNpxfguQNkc2CIzM0xNk5QLedCEZm1VKsf2XrAXMNrA2vVcq4ZJ4DhvCSAeSALXASuLBTW129U6oPrT969AK4Bq0AeWARs4BRgieMUEkgDmeO9ANipzDnH//nFB0KgAxwATaAFeID5DQNatLGdaXOWAAAAAElFTkSuQmCC) no-repeat scroll 0px 5px;
|
||||
padding:4px 0 4px 20px;
|
||||
}
|
||||
</style>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<script>
|
||||
(function($){
|
||||
$.fn.tablesorter = function() {
|
||||
var $table = this;
|
||||
this.find('th').click(function() {
|
||||
var idx = $(this).index();
|
||||
var direction = $(this).hasClass('sort_asc');
|
||||
$table.tablesortby(idx,direction);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
$.fn.tablesortby = function(idx,direction) {
|
||||
var $rows = this.find('tbody tr');
|
||||
function elementToVal(a) {
|
||||
var $a_elem = $(a).find('td:nth-child('+(idx+1)+')');
|
||||
var a_val = $a_elem.attr('data-sort') || $a_elem.text();
|
||||
return (a_val == parseInt(a_val) ? parseInt(a_val) : a_val);
|
||||
}
|
||||
$rows.sort(function(a,b){
|
||||
var a_val = elementToVal(a), b_val = elementToVal(b);
|
||||
return (a_val > b_val ? 1 : (a_val == b_val ? 0 : -1)) * (direction ? 1 : -1);
|
||||
})
|
||||
this.find('th').removeClass('sort_asc sort_desc');
|
||||
$(this).find('thead th:nth-child('+(idx+1)+')').addClass(direction ? 'sort_desc' : 'sort_asc');
|
||||
for(var i =0;i<$rows.length;i++)
|
||||
this.append($rows[i]);
|
||||
this.settablesortmarkers();
|
||||
return this;
|
||||
}
|
||||
$.fn.retablesort = function() {
|
||||
var $e = this.find('thead th.sort_asc, thead th.sort_desc');
|
||||
if($e.length)
|
||||
this.tablesortby($e.index(), $e.hasClass('sort_desc') );
|
||||
|
||||
return this;
|
||||
}
|
||||
$.fn.settablesortmarkers = function() {
|
||||
this.find('thead th span.indicator').remove();
|
||||
this.find('thead th.sort_asc').append('<span class="indicator">↓<span>');
|
||||
this.find('thead th.sort_desc').append('<span class="indicator">↑<span>');
|
||||
return this;
|
||||
}
|
||||
})(jQuery);
|
||||
$(function(){
|
||||
var XSRF = (document.cookie.match('(^|; )_sfm_xsrf=([^;]*)')||0)[2];
|
||||
var MAX_UPLOAD_SIZE = <?php echo $MAX_UPLOAD_SIZE ?>;
|
||||
var $tbody = $('#list');
|
||||
$(window).on('hashchange',list).trigger('hashchange');
|
||||
$('#table').tablesorter();
|
||||
|
||||
$('#table').on('click','.delete',function(data) {
|
||||
$.post("",{'do':'delete',file:$(this).attr('data-file'),xsrf:XSRF},function(response){
|
||||
list();
|
||||
},'json');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#mkdir').submit(function(e) {
|
||||
var hashval = decodeURIComponent(window.location.hash.substr(1)),
|
||||
$dir = $(this).find('[name=name]');
|
||||
e.preventDefault();
|
||||
$dir.val().length && $.post('?',{'do':'mkdir',name:$dir.val(),xsrf:XSRF,file:hashval},function(data){
|
||||
list();
|
||||
},'json');
|
||||
$dir.val('');
|
||||
return false;
|
||||
});
|
||||
<?php if($allow_upload): ?>
|
||||
// file upload stuff
|
||||
$('#file_drop_target').on('dragover',function(){
|
||||
$(this).addClass('drag_over');
|
||||
return false;
|
||||
}).on('dragend',function(){
|
||||
$(this).removeClass('drag_over');
|
||||
return false;
|
||||
}).on('drop',function(e){
|
||||
e.preventDefault();
|
||||
var files = e.originalEvent.dataTransfer.files;
|
||||
$.each(files,function(k,file) {
|
||||
uploadFile(file);
|
||||
});
|
||||
$(this).removeClass('drag_over');
|
||||
});
|
||||
$('input[type=file]').change(function(e) {
|
||||
e.preventDefault();
|
||||
$.each(this.files,function(k,file) {
|
||||
uploadFile(file);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function uploadFile(file) {
|
||||
var folder = decodeURIComponent(window.location.hash.substr(1));
|
||||
|
||||
if(file.size > MAX_UPLOAD_SIZE) {
|
||||
var $error_row = renderFileSizeErrorRow(file,folder);
|
||||
$('#upload_progress').append($error_row);
|
||||
window.setTimeout(function(){$error_row.fadeOut();},5000);
|
||||
return false;
|
||||
}
|
||||
|
||||
var $row = renderFileUploadRow(file,folder);
|
||||
$('#upload_progress').append($row);
|
||||
var fd = new FormData();
|
||||
fd.append('file_data',file);
|
||||
fd.append('file',folder);
|
||||
fd.append('xsrf',XSRF);
|
||||
fd.append('do','upload');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', '?');
|
||||
xhr.onload = function() {
|
||||
$row.remove();
|
||||
list();
|
||||
};
|
||||
xhr.upload.onprogress = function(e){
|
||||
if(e.lengthComputable) {
|
||||
$row.find('.progress').css('width',(e.loaded/e.total*100 | 0)+'%' );
|
||||
}
|
||||
};
|
||||
xhr.send(fd);
|
||||
}
|
||||
function renderFileUploadRow(file,folder) {
|
||||
return $row = $('<div/>')
|
||||
.append( $('<span class="fileuploadname" />').text( (folder ? folder+'/':'')+file.name))
|
||||
.append( $('<div class="progress_track"><div class="progress"></div></div>') )
|
||||
.append( $('<span class="size" />').text(formatFileSize(file.size)) )
|
||||
};
|
||||
function renderFileSizeErrorRow(file,folder) {
|
||||
return $row = $('<div class="error" />')
|
||||
.append( $('<span class="fileuploadname" />').text( 'Error: ' + (folder ? folder+'/':'')+file.name))
|
||||
.append( $('<span/>').html(' file size - <b>' + formatFileSize(file.size) + '</b>'
|
||||
+' exceeds max upload size of <b>' + formatFileSize(MAX_UPLOAD_SIZE) + '</b>') );
|
||||
}
|
||||
<?php endif; ?>
|
||||
function list() {
|
||||
var hashval = window.location.hash.substr(1);
|
||||
$.get('?do=list&file='+ hashval,function(data) {
|
||||
$tbody.empty();
|
||||
$('#breadcrumb').empty().html(renderBreadcrumbs(hashval));
|
||||
if(data.success) {
|
||||
$.each(data.results,function(k,v){
|
||||
$tbody.append(renderFileRow(v));
|
||||
});
|
||||
!data.results.length && $tbody.append('<tr><td class="empty" colspan=5>This folder is empty</td></tr>')
|
||||
data.is_writable ? $('body').removeClass('no_write') : $('body').addClass('no_write');
|
||||
} else {
|
||||
console.warn(data.error.msg);
|
||||
}
|
||||
$('#table').retablesort();
|
||||
},'json');
|
||||
}
|
||||
function renderFileRow(data) {
|
||||
var $link = $('<a class="name" />')
|
||||
.attr('href', data.is_dir ? '#' + encodeURIComponent(data.path) : './' + data.path)
|
||||
.text(data.name);
|
||||
var allow_direct_link = <?php echo $allow_direct_link?'true':'false'; ?>;
|
||||
if (!data.is_dir && !allow_direct_link) $link.css('pointer-events','none');
|
||||
var $dl_link = $('<a/>').attr('href','?do=download&file='+ encodeURIComponent(data.path))
|
||||
.addClass('download').text('download');
|
||||
var $delete_link = $('<a href="#" />').attr('data-file',data.path).addClass('delete').text('delete');
|
||||
var perms = [];
|
||||
if(data.is_readable) perms.push('read');
|
||||
if(data.is_writable) perms.push('write');
|
||||
if(data.is_executable) perms.push('exec');
|
||||
var $html = $('<tr />')
|
||||
.addClass(data.is_dir ? 'is_dir' : '')
|
||||
.append( $('<td class="first" />').append($link) )
|
||||
.append( $('<td/>').attr('data-sort',data.is_dir ? -1 : data.size)
|
||||
.html($('<span class="size" />').text(formatFileSize(data.size))) )
|
||||
.append( $('<td/>').attr('data-sort',data.mtime).text(formatTimestamp(data.mtime)) )
|
||||
.append( $('<td/>').text(perms.join('+')) )
|
||||
.append( $('<td/>').append($dl_link).append( data.is_deleteable ? $delete_link : '') )
|
||||
return $html;
|
||||
}
|
||||
function renderBreadcrumbs(path) {
|
||||
var base = "",
|
||||
$html = $('<div/>').append( $('<a href=#>Home</a></div>') );
|
||||
$.each(path.split('%2F'),function(k,v){
|
||||
if(v) {
|
||||
var v_as_text = decodeURIComponent(v);
|
||||
$html.append( $('<span/>').text(' ▸ ') )
|
||||
.append( $('<a/>').attr('href','#'+base+v).text(v_as_text) );
|
||||
base += v + '%2F';
|
||||
}
|
||||
});
|
||||
return $html;
|
||||
}
|
||||
function formatTimestamp(unix_timestamp) {
|
||||
var m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
var d = new Date(unix_timestamp*1000);
|
||||
return [m[d.getMonth()],' ',d.getDate(),', ',d.getFullYear()," ",
|
||||
(d.getHours() % 12 || 12),":",(d.getMinutes() < 10 ? '0' : '')+d.getMinutes(),
|
||||
" ",d.getHours() >= 12 ? 'PM' : 'AM'].join('');
|
||||
}
|
||||
function formatFileSize(bytes) {
|
||||
var s = ['bytes', 'KB','MB','GB','TB','PB','EB'];
|
||||
for(var pos = 0;bytes >= 1000; pos++,bytes /= 1024);
|
||||
var d = Math.round(bytes*10);
|
||||
return pos ? [parseInt(d/10),".",d%10," ",s[pos]].join('') : bytes + ' bytes';
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
</head><body>
|
||||
<script>
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
</script>
|
||||
<div id="top">
|
||||
<?php if($allow_create_folder): ?>
|
||||
<form action="?" method="post" id="mkdir" />
|
||||
<label for=dirname>Create New Folder</label><input id=dirname type=text name=name value="" />
|
||||
<input type="submit" value="create" />
|
||||
</form>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($allow_upload): ?>
|
||||
|
||||
<div id="file_drop_target">
|
||||
Drag Files Here To Upload
|
||||
<b>or</b>
|
||||
<input type="file" multiple />
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="breadcrumb"> </div>
|
||||
</div>
|
||||
|
||||
<div id="upload_progress"></div>
|
||||
<table id="table"><thead><tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Modified</th>
|
||||
<th>Permissions</th>
|
||||
<th>Actions</th>
|
||||
</tr></thead><tbody id="list">
|
||||
|
||||
</tbody></table>
|
||||
<footer><a onclick="lockRoot()">Index of <?php echo preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__); ?> | Press to lock root on this browser</a></footer>
|
||||
<script>
|
||||
function lockRoot() {
|
||||
document.cookie = "PHPSESSID=; expires = Thu, 01 Jan 1970 00:00:00 GMT"
|
||||
document.cookie = "_sfm_xsrf=; expires = Thu, 01 Jan 1970 00:00:00 GMT"
|
||||
window.location.href = '/home/user/index.php';
|
||||
} // If you are like me and use the same browsing session for ages at a time, this can easily prevent usage of the root file browser.
|
||||
</script>
|
||||
</body></html>
|
|
@ -1,5 +1,5 @@
|
|||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
$(function() {
|
||||
|
||||
// Set the command-line prompt to include the user's IP Address
|
||||
//$('.prompt').html('[' + codehelper_ip["IP"] + '@HTML5] # ');
|
||||
$('.prompt').html('[user@DremJS] # ');
|
||||
|
|
|
@ -9,6 +9,8 @@ var moduleCode = [];
|
|||
var modInstall;
|
||||
var firstLine = "";
|
||||
|
||||
document.addEventListener('contextmenu', event => event.preventDefault());
|
||||
|
||||
util.toArray = function(list) {
|
||||
return Array.prototype.slice.call(list || [], 0);
|
||||
};
|
||||
|
|