diff --git a/LZCompressor/LZContext.php b/LZCompressor/LZContext.php
new file mode 100644
index 0000000..0e41a3e
--- /dev/null
+++ b/LZCompressor/LZContext.php
@@ -0,0 +1,91 @@
+data = new LZData;
+ }
+
+ // Helper
+
+ /**
+ * @param string $val
+ * @return bool
+ */
+ public function dictionaryContains($val) {
+ return array_key_exists($val, $this->dictionary);
+ }
+
+ /**
+ * @param $val
+ */
+ public function addToDictionary($val) {
+ $this->dictionary[$val] = $this->dictSize++;
+ }
+
+ /**
+ * @param string $val
+ * @return bool
+ */
+ public function dictionaryToCreateContains($val) {
+ return array_key_exists($val, $this->dictionaryToCreate);
+ }
+
+ /**
+ * decrements enlargeIn and extends numbits in case enlargeIn drops to 0
+ */
+ public function enlargeIn() {
+ $this->enlargeIn--;
+ if($this->enlargeIn==0) {
+ $this->enlargeIn = pow(2, $this->numBits);
+ $this->numBits++;
+ }
+ }
+}
diff --git a/LZCompressor/LZData.php b/LZCompressor/LZData.php
new file mode 100644
index 0000000..b536ce1
--- /dev/null
+++ b/LZCompressor/LZData.php
@@ -0,0 +1,29 @@
+str .= $str;
+ }
+}
diff --git a/LZCompressor/LZReverseDictionary.php b/LZCompressor/LZReverseDictionary.php
new file mode 100644
index 0000000..264caa4
--- /dev/null
+++ b/LZCompressor/LZReverseDictionary.php
@@ -0,0 +1,33 @@
+entries);
+ }
+
+ public function hasEntry($index) {
+ return array_key_exists($index, $this->entries);
+ }
+
+ public function getEntry($index) {
+ return $this->entries[$index];
+ }
+
+ public function addEntry($char) {
+ $this->entries[] = $char;
+ }
+
+}
\ No newline at end of file
diff --git a/LZCompressor/LZString.php b/LZCompressor/LZString.php
new file mode 100644
index 0000000..75791fa
--- /dev/null
+++ b/LZCompressor/LZString.php
@@ -0,0 +1,286 @@
+c = LZUtil::utf8_charAt($uncompressed, $ii);
+ if(!$context->dictionaryContains($context->c)) {
+ $context->addToDictionary($context->c);
+ $context->dictionaryToCreate[$context->c] = true;
+ }
+ $context->wc = $context->w . $context->c;
+ if($context->dictionaryContains($context->wc)) {
+ $context->w = $context->wc;
+ } else {
+ self::produceW($context, $bitsPerChar, $getCharFromInt);
+ }
+ }
+ if($context->w !== '') {
+ self::produceW($context, $bitsPerChar, $getCharFromInt);
+ }
+
+ $value = 2;
+ for($i=0; $i<$context->numBits; $i++) {
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
+ $value = $value >> 1;
+ }
+
+ while (true) {
+ $context->data->val = $context->data->val << 1;
+ if ($context->data->position == ($bitsPerChar-1)) {
+ $context->data->append($getCharFromInt($context->data->val));
+ break;
+ }
+ $context->data->position++;
+ }
+
+ return $context->data->str;
+ }
+
+ /**
+ * @param LZContext $context
+ * @param integer $bitsPerChar
+ * @param callable $getCharFromInt
+ *
+ * @return LZContext
+ */
+ private static function produceW(LZContext $context, $bitsPerChar, $getCharFromInt)
+ {
+ if($context->dictionaryToCreateContains($context->w)) {
+ if(LZUtil::charCodeAt($context->w)<256) {
+ for ($i=0; $i<$context->numBits; $i++) {
+ self::writeBit(null, $context->data, $bitsPerChar, $getCharFromInt);
+ }
+ $value = LZUtil::charCodeAt($context->w);
+ for ($i=0; $i<8; $i++) {
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
+ $value = $value >> 1;
+ }
+ } else {
+ $value = 1;
+ for ($i=0; $i<$context->numBits; $i++) {
+ self::writeBit($value, $context->data, $bitsPerChar, $getCharFromInt);
+ $value = 0;
+ }
+ $value = LZUtil::charCodeAt($context->w);
+ for ($i=0; $i<16; $i++) {
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
+ $value = $value >> 1;
+ }
+ }
+ $context->enlargeIn();
+ unset($context->dictionaryToCreate[$context->w]);
+ } else {
+ $value = $context->dictionary[$context->w];
+ for ($i=0; $i<$context->numBits; $i++) {
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
+ $value = $value >> 1;
+ }
+ }
+ $context->enlargeIn();
+ $context->addToDictionary($context->wc);
+ $context->w = $context->c.'';
+ }
+
+ /**
+ * @param string $value
+ * @param LZData $data
+ * @param integer $bitsPerChar
+ * @param callable $getCharFromInt
+ */
+ private static function writeBit($value, LZData $data, $bitsPerChar, $getCharFromInt)
+ {
+ if(null !== $value) {
+ $data->val = ($data->val << 1) | $value;
+ } else {
+ $data->val = ($data->val << 1);
+ }
+ if ($data->position == ($bitsPerChar-1)) {
+ $data->position = 0;
+ $data->append($getCharFromInt($data->val));
+ $data->val = 0;
+ } else {
+ $data->position++;
+ }
+ }
+
+ /**
+ * @param LZData $data
+ * @param integer $resetValue
+ * @param callable $getNextValue
+ * @param integer $exponent
+ * @param string $feed
+ * @return integer
+ */
+ private static function readBits(LZData $data, $resetValue, $getNextValue, $feed, $exponent)
+ {
+ $bits = 0;
+ $maxPower = pow(2, $exponent);
+ $power=1;
+ while($power != $maxPower) {
+ $resb = $data->val & $data->position;
+ $data->position >>= 1;
+ if ($data->position == 0) {
+ $data->position = $resetValue;
+ $data->val = $getNextValue($feed, $data->index++);
+ }
+ $bits |= (($resb>0 ? 1 : 0) * $power);
+ $power <<= 1;
+ }
+ return $bits;
+ }
+
+ /**
+ * @param string $compressed
+ * @param integer $resetValue
+ * @param callable $getNextValue
+ * @return string
+ */
+ private static function _decompress($compressed, $resetValue, $getNextValue)
+ {
+ if(!is_string($compressed) || strlen($compressed) === 0) {
+ return '';
+ }
+
+ $length = LZUtil::utf8_strlen($compressed);
+ $entry = null;
+ $enlargeIn = 4;
+ $numBits = 3;
+ $result = '';
+
+ $dictionary = new LZReverseDictionary();
+
+ $data = new LZData();
+ $data->str = $compressed;
+ $data->val = $getNextValue($compressed, 0);
+ $data->position = $resetValue;
+ $data->index = 1;
+
+ $next = self::readBits($data, $resetValue, $getNextValue, $compressed, 2);
+
+ if($next < 0 || $next > 1) {
+ return '';
+ }
+
+ $exponent = ($next == 0) ? 8 : 16;
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, $exponent);
+
+ $c = LZUtil::fromCharCode($bits);
+ $dictionary->addEntry($c);
+ $w = $c;
+
+ $result .= $c;
+
+ while(true) {
+ if($data->index > $length) {
+ return '';
+ }
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, $numBits);
+
+ $c = $bits;
+
+ switch($c) {
+ case 0:
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, 8);
+ $c = $dictionary->size();
+ $dictionary->addEntry(LZUtil::fromCharCode($bits));
+ $enlargeIn--;
+ break;
+ case 1:
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, 16);
+ $c = $dictionary->size();
+ $dictionary->addEntry(LZUtil::fromCharCode($bits));
+ $enlargeIn--;
+ break;
+ case 2:
+ return $result;
+ break;
+ }
+
+ if($enlargeIn == 0) {
+ $enlargeIn = pow(2, $numBits);
+ $numBits++;
+ }
+
+ if($dictionary->hasEntry($c)) {
+ $entry = $dictionary->getEntry($c);
+ }
+ else {
+ if ($c == $dictionary->size()) {
+ $entry = $w . $w{0};
+ } else {
+ return null;
+ }
+ }
+
+ $result .= $entry;
+ $dictionary->addEntry($w . $entry{0});
+ $w = $entry;
+
+ $enlargeIn--;
+ if($enlargeIn == 0) {
+ $enlargeIn = pow(2, $numBits);
+ $numBits++;
+ }
+ }
+ }
+}
diff --git a/LZCompressor/LZUtil.php b/LZCompressor/LZUtil.php
new file mode 100644
index 0000000..4b27a1e
--- /dev/null
+++ b/LZCompressor/LZUtil.php
@@ -0,0 +1,112 @@
+ 1) return ($h & 0x1F) << 6 | (ord($ch{1}) & 0x3F);
+ if ($h <= 0xEF && $len > 2) return ($h & 0x0F) << 12 | (ord($ch{1}) & 0x3F) << 6 | (ord($ch{2}) & 0x3F);
+ if ($h <= 0xF4 && $len > 3)
+ return ($h & 0x0F) << 18 | (ord($ch{1}) & 0x3F) << 12 | (ord($ch{2}) & 0x3F) << 6 | (ord($ch{3}) & 0x3F);
+ return -2;
+ }
+
+ /**
+ * @param string $str
+ * @param integer $num
+ *
+ * @return string
+ */
+ public static function utf8_charAt($str, $num)
+ {
+ return mb_substr($str, $num, 1, 'UTF-8');
+ }
+
+ /**
+ * @param string $str
+ * @return integer
+ */
+ public static function utf8_strlen($str) {
+ return mb_strlen($str, 'UTF-8');
+ }
+
+
+}
\ No newline at end of file
diff --git a/editor.php b/editor.php
index 2b3f680..4e13ff2 100644
--- a/editor.php
+++ b/editor.php
@@ -5,7 +5,7 @@ $t = $text['editor'];
?>
-
+
ICEcoder v editor
@@ -287,6 +287,14 @@ function createNewCMInstance(num) {
window['cM'+num] .on("inputRead", function(thisCM) {top.ICEcoder.cMonInputRead(thisCM,'cM'+num)});
window['cM'+num+'diff'] .on("inputRead", function(thisCM) {top.ICEcoder.cMonInputRead(thisCM,'cM'+num+'diff')});
+ // Gutter Click
+ window['cM'+num] .on("gutterClick", function(thisCM,line,gutter,evt) {top.ICEcoder.cMonGutterClick(thisCM,line,gutter,evt,'cM'+num)});
+ window['cM'+num+'diff'] .on("gutterClick", function(thisCM,line,gutter,evt) {top.ICEcoder.cMonGutterClick(thisCM,line,gutter,evt,'cM'+num+'diff')});
+
+ // Mouse Down
+ window['cM'+num] .on("mousedown", function(thisCM) {top.ICEcoder.cMonMouseDown(thisCM,'cM'+num)});
+ window['cM'+num+'diff'] .on("mousedown", function(thisCM) {top.ICEcoder.cMonMouseDown(thisCM,'cM'+num+'diff')});
+
// Render line
window['cM'+num] .on("renderLine", function(thisCM, line, element) {top.ICEcoder.cMonRenderLine(thisCM,'cM'+num,line,element)});
window['cM'+num+'diff'] .on("renderLine", function(thisCM, line, element) {top.ICEcoder.cMonRenderLine(thisCM,'cM'+num+'diff',line,element)});
diff --git a/files.php b/files.php
index a6e1ef9..8b88150 100644
--- a/files.php
+++ b/files.php
@@ -8,7 +8,7 @@ $isGitHubRepoDir = in_array($ICEcoder["root"],$ICEcoder['githubLocalPaths']);
?>
-
+
ICEcoder v file manager
diff --git a/index.php b/index.php
index 516dcf6..1e0f052 100644
--- a/index.php
+++ b/index.php
@@ -37,7 +37,7 @@ if ($ICEcoder["checkUpdates"]) {
$isMac = strpos($_SERVER['HTTP_USER_AGENT'], "Macintosh")>-1 ? true : false;
?>
-
+
ICEcoder v
@@ -80,6 +80,7 @@ $t = $text['index'];
+
@@ -252,7 +253,7 @@ $t = $text['index'];
-
+
diff --git a/lib/file-control-xhr.php b/lib/file-control-xhr.php
index f6d4daa..a5e2383 100644
--- a/lib/file-control-xhr.php
+++ b/lib/file-control-xhr.php
@@ -4,6 +4,14 @@ include("settings.php");
include("ftp-control.php");
$t = $text['file-control'];
+// Load the LZ String PHP libs and define using LZString
+include(dirname(__FILE__)."/../LZCompressor/LZContext.php");
+include(dirname(__FILE__)."/../LZCompressor/LZData.php");
+include(dirname(__FILE__)."/../LZCompressor/LZReverseDictionary.php");
+include(dirname(__FILE__)."/../LZCompressor/LZString.php");
+include(dirname(__FILE__)."/../LZCompressor/LZUtil.php");
+use LZCompressor\LZString as LZString;
+
// ===============================
// SET OUR ERROR INFO TO A DEFAULT
// ===============================
@@ -21,11 +29,11 @@ $saveType = isset($_GET['saveType']) ? strClean($_GET['saveType']) : "";
// Establish the filename/new filename
if (isset($_POST['newFileName']) && $_POST['newFileName']!="") {
- $file = $_POST['newFileName']; // New file
+ $file = strClean($_POST['newFileName']); // New file
} elseif (isset($_REQUEST['file'])) {
- $file = $_REQUEST['file']; // Existing file
+ $file = strClean($_REQUEST['file']); // Existing file
} else {
- $file = ""; // Error
+ $file = ""; // Error
$finalAction = "nothing";
$doNext = "";
$error = true;
@@ -33,6 +41,14 @@ if (isset($_POST['newFileName']) && $_POST['newFileName']!="") {
$errorMsg = $t['Sorry, bad filename...'];
};
+// If we have changes or whole content, we need to LZ decompress them
+if (isset($_POST['changes'])) {
+ $_POST['changes'] = LZString::decompressFromBase64($_POST['changes']);
+}
+if (isset($_POST['contents'])) {
+ $_POST['contents'] = LZString::decompressFromBase64($_POST['contents']);
+}
+
// If we have file(s) to work with...
if (!$error) {
// Replace pipes with slashes, after cleaning the chars
@@ -148,7 +164,7 @@ function stitchChanges($fileLines) {
$fileLines[$j] = "";
// If the last line, clear line returns from it
if ($j == count($fileLines)-1) {
- $fileLines[$changes[$i][1]-1] = rtrim(rtrim(rtrim($fileLines[$changes[$i][1]-1],"\n"),"\r"),"\r\n");
+ $fileLines[$changes[$i][1]-1] = rtrim(rtrim($fileLines[$changes[$i][1]-1],"\r"),"\n");
}
}
}
@@ -228,7 +244,7 @@ if (!$error && $_GET['action']=="save") {
/* console.log(\'Calling \'+saveURL+\' via XHR\'); */
xhr.open("POST",saveURL,true);
xhr.setRequestHeader(\'Content-type\', \'application/x-www-form-urlencoded\');
- xhr.send(\'timeStart='.$_POST["timeStart"].'&file='.$fileURL.'&newFileName=\'+newFileName.replace(/\\\+/g,"%2B")+\'&contents=\'+top.ICEcoder.saveAsContent);
+ xhr.send(\'timeStart='.$_POST["timeStart"].'&file='.$fileURL.'&newFileName=\'+newFileName.replace(/\\\+/g,"%2B")+\'&contents=\'+encodeURIComponent(top.LZString.compressToBase64(top.ICEcoder.saveAsContent)));
top.ICEcoder.serverMessage("'.$t['Saving'].'
" + "'.($finalAction == "Save" ? "newFileName" : "'".$fileName."'").'");
}
}
@@ -266,11 +282,25 @@ if (!$error && $_GET['action']=="save") {
if (isset($ftpSite)) {
$ftpFilepath = ltrim($fileLoc."/".$fileName,"/");
if (isset($_POST['changes'])) {
- // Get existing file contents as lines and stitch changes onto it
- $contents = toUTF8noBOM(ftpGetContents($ftpConn, $ftpRoot.$ftpFilepath, $ftpMode));
- $contents = explode("\n",$contents);
- $fileLines = file($file);
+ // Get existing file contents as lines
+ $loadedFile = toUTF8noBOM(ftpGetContents($ftpConn, $ftpRoot.$fileLoc."/".$fileName, $ftpMode));
+ $fileLines = explode("\n",$loadedFile);
+ // Need to add a new line at the end of each because explode will lose them,
+ // want want to end up with same array that 'file($file)' produces for a local file
+ // - it keeps the line endings at the end of each array item
+ for ($i=0; $i 0) || ($windowsNewLines > 0)){
+ if ($unixNewLines > $windowsNewLines){
+ $contents = str_replace($ICEcoder["lineEnding"], "\n", $contents);
+ } elseif ($windowsNewLines > $unixNewLines){
+ $contents = str_replace($ICEcoder["lineEnding"], "\r\n", $contents);
+ }
+ }
// Write our file contents
if (!ftpWriteFile($ftpConn, $ftpFilepath, $contents, $ftpMode)) {
$doNext .= 'top.ICEcoder.message("Sorry, could not write '.$ftpFilepath.' at '.$ftpHost.'");';
@@ -291,25 +328,26 @@ if (!$error && $_GET['action']=="save") {
// Get existing file contents as lines and stitch changes onto it
$fileLines = file($file);
$contents = stitchChanges($fileLines);
+
+ // get old file contents, and count stats on usage \n and \r there
+ // in this case we can keep line endings, which file had before, without
+ // making code version control systems going crazy about line endings change in whole file.
+ $oldContents = file_exists($file)?file_get_contents($file):'';
+ $unixNewLines = preg_match_all('/[^\r][\n]/u', $oldContents);
+ $windowsNewLines = preg_match_all('/[\r][\n]/u', $oldContents);
} else {
$contents = $_POST['contents'];
}
// Newly created files have the perms set too
$setPerms = (!file_exists($file)) ? true : false;
- // get old file contents, if file exists, and count stats on usage \n and \r there
- // in this case we can keep line endings, which file had before, without
- // making code version control systems going crazy about line endings change in whole file.
- $oldContents = file_exists($file)?file_get_contents($file):'';
- $unixNewLines = preg_match_all('/[^\r][\n]/u', $oldContents);
- $windowsNewLines = preg_match_all('/[\r][\n]/u', $oldContents);
$fh = fopen($file, 'w') or die($t['Sorry, cannot save']);
// replace \r\n (Windows), \r (old Mac) and \n (Linux) line endings with whatever we chose to be lineEnding
$contents = str_replace("\r\n", $ICEcoder["lineEnding"], $contents);
$contents = str_replace("\r", $ICEcoder["lineEnding"], $contents);
$contents = str_replace("\n", $ICEcoder["lineEnding"], $contents);
- if (($unixNewLines > 0) || ($windowsNewLines > 0)){
+ if (isset($_POST['changes']) && ($unixNewLines > 0) || ($windowsNewLines > 0)){
if ($unixNewLines > $windowsNewLines){
$contents = str_replace($ICEcoder["lineEnding"], "\n", $contents);
} elseif ($windowsNewLines > $unixNewLines){
@@ -512,7 +550,7 @@ if (!$error && $_GET['action']=="save") {
// ==========
if (!$error && $_GET['action']=="newFolder") {
- if (!$demoMode && ($ftpSite || is_writable($docRoot.$fileLoc))) {
+ if (!$demoMode && (isset($ftpSite) || is_writable($docRoot.$fileLoc))) {
$updateFM = false;
// FTP
if (isset($ftpSite)) {
@@ -555,7 +593,7 @@ if (!$error && $_GET['action']=="move") {
$tgtDir = $docRoot.$fileLoc."/".$fileName;
}
if ($srcDir != $tgtDir && $fileLoc != "") {
- if (!$demoMode && ($ftpSite || is_writable($srcDir))) {
+ if (!$demoMode && (isset($ftpSite) || is_writable($srcDir))) {
$updateFM = false;
// FTP
if (isset($ftpSite)) {
@@ -576,7 +614,7 @@ if (!$error && $_GET['action']=="move") {
}
// Update file manager on success
if ($updateFM) {
- $doNext .= 'top.ICEcoder.selectedFiles=[];top.ICEcoder.updateFileManagerList(\'move\',\''.$fileLoc.'\',\''.$fileName.'\',\'\',\''.str_replace($iceRoot,"",strClean(str_replace("|","/",$_GET['oldFileName']))).'\',false,$fileOrFolder);';
+ $doNext .= 'top.ICEcoder.selectedFiles=[];top.ICEcoder.updateFileManagerList(\'move\',\''.$fileLoc.'\',\''.$fileName.'\',\'\',\''.str_replace($iceRoot,"",strClean(str_replace("|","/",$_GET['oldFileName']))).'\',false,\''.$fileOrFolder.'\');';
}
$finalAction = "move";
// Run our custom processes
@@ -597,7 +635,7 @@ if (!$error && $_GET['action']=="move") {
// ==================
if (!$error && $_GET['action']=="rename") {
- if (!$demoMode && ($ftpSite || is_writable($docRoot.$iceRoot.str_replace("|","/",strClean($_GET['oldFileName']))))) {
+ if (!$demoMode && (isset($ftpSite) || is_writable($docRoot.$iceRoot.str_replace("|","/",strClean($_GET['oldFileName']))))) {
$updateFM = false;
// FTP
if (isset($ftpSite)) {
@@ -871,7 +909,7 @@ if (!isset($ftpSite) && !$error && $_GET['action']=="getRemoteFile") {
// =======================
if (!$error && $_GET['action']=="perms") {
- if (!$demoMode && ($ftpSite || is_writable($file))) {
+ if (!$demoMode && (isset($ftpSite) || is_writable($file))) {
$updateFM = false;
// FTP
if (isset($ftpSite)) {
@@ -917,7 +955,7 @@ if (!isset($ftpSite) && !$error && $_GET['action']=="checkExists") {
// ===================
// No $filemtime yet? Get it now!
-if (!isset($filemtime)) {
+if (!isset($filemtime) && !is_dir($file)) {
$filemtime = $serverType=="Linux" ? filemtime($file) : "1000000";
}
// Set $timeStart, use 0 if not available
@@ -937,7 +975,7 @@ if (isset($ftpSite)) {
} else {
$itemAbsPath = $file;
$itemPath = dirname($file);
- $itemBytes = filesize($file);
+ $itemBytes = is_dir($file) ? null : filesize($file);
$itemType = (file_exists($file) ? (is_dir($file) ? "dir" : "file") : "unknown");
$itemExists = (file_exists($file) ? "true" : "false");
}
diff --git a/lib/file-control.php b/lib/file-control.php
index f1fcd37..9d2946b 100644
--- a/lib/file-control.php
+++ b/lib/file-control.php
@@ -3,6 +3,14 @@ include("headers.php");
include("settings.php");
include("ftp-control.php");
$t = $text['file-control'];
+
+// Load the LZ String PHP libs and define using LZString
+include(dirname(__FILE__)."/../LZCompressor/LZContext.php");
+include(dirname(__FILE__)."/../LZCompressor/LZData.php");
+include(dirname(__FILE__)."/../LZCompressor/LZReverseDictionary.php");
+include(dirname(__FILE__)."/../LZCompressor/LZString.php");
+include(dirname(__FILE__)."/../LZCompressor/LZUtil.php");
+use LZCompressor\LZString as LZString;
?>
@@ -102,7 +110,7 @@ if ($_GET['action']=="load") {
$encoding=ini_get("default_charset");
if($encoding=="")
$encoding="UTF-8";
- echo '