From 41e8e9828368cfae0469414b241de23b2f2a2808 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 23 Aug 2017 14:16:06 +0700 Subject: [PATCH 001/118] Setup env for XenForo 2 --- dev-scripts/Dockerfile.php-apache | 2 +- dev-scripts/docker/cmd.sh | 2 +- dev-scripts/docker/find-addons.sh | 10 - dev-scripts/docker/find-addons2.sh | 10 + router.php | 4 +- src/addons/DevHelper/Autoloader.php | 77 +++++ src/addons/DevHelper/DevHelper/Hint/XF.php | 9 + src/addons/DevHelper/Router.php | 161 ++++++++++ src/addons/DevHelper/StreamWrapper.php | 327 +++++++++++++++++++++ src/addons/DevHelper/XF/AddOn/Manager.php | 73 +++++ src/addons/DevHelper/XF/Extension.php | 28 ++ src/addons/DevHelper/XF/XF.php | 11 + src/addons/DevHelper/addon.json | 6 + 13 files changed, 706 insertions(+), 14 deletions(-) delete mode 100644 dev-scripts/docker/find-addons.sh create mode 100644 dev-scripts/docker/find-addons2.sh create mode 100644 src/addons/DevHelper/Autoloader.php create mode 100644 src/addons/DevHelper/DevHelper/Hint/XF.php create mode 100644 src/addons/DevHelper/Router.php create mode 100644 src/addons/DevHelper/StreamWrapper.php create mode 100644 src/addons/DevHelper/XF/AddOn/Manager.php create mode 100644 src/addons/DevHelper/XF/Extension.php create mode 100644 src/addons/DevHelper/XF/XF.php create mode 100644 src/addons/DevHelper/addon.json diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index f43b292..b7fb859 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -12,6 +12,6 @@ RUN pecl install apcu \ COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/cmd.sh \ - && chmod +x /usr/local/bin/find-addons.sh + && chmod +x /usr/local/bin/find-addons2.sh CMD ["/usr/local/bin/cmd.sh"] diff --git a/dev-scripts/docker/cmd.sh b/dev-scripts/docker/cmd.sh index 3633003..8a5f914 100644 --- a/dev-scripts/docker/cmd.sh +++ b/dev-scripts/docker/cmd.sh @@ -2,6 +2,6 @@ set -e -find-addons.sh +find-addons2.sh exec apache2-foreground diff --git a/dev-scripts/docker/find-addons.sh b/dev-scripts/docker/find-addons.sh deleted file mode 100644 index bd5c8f4..0000000 --- a/dev-scripts/docker/find-addons.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -e - -cd /var/www/html/ - -{ \ - echo "# Generated by $0"; \ - find addons/ -maxdepth 5 -name library -type d | grep -v .git | sed 's#/library$##'; \ -} > ./xenforo/internal_data/addons.txt diff --git a/dev-scripts/docker/find-addons2.sh b/dev-scripts/docker/find-addons2.sh new file mode 100644 index 0000000..70c7b30 --- /dev/null +++ b/dev-scripts/docker/find-addons2.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +cd /var/www/html/ + +{ \ + echo "# Generated by $0"; \ + find addons/ -maxdepth 5 -name src -type d | grep -v .git | sed 's#/src##'; \ +} > ./xenforo/internal_data/addons2.txt diff --git a/router.php b/router.php index 1c857b1..563c29a 100644 --- a/router.php +++ b/router.php @@ -1,4 +1,4 @@ _setup) { + return; + } + + /** @var \Composer\Autoload\ClassLoader $autoLoader */ + /** @noinspection PhpIncludeInspection */ + $autoLoader = require('/var/www/html/xenforo/src/vendor/autoload.php'); + + list(, $addOnPaths) = Router::getLocatePaths(); + foreach ($addOnPaths as $addOnPath) { + $globPattern = $addOnPath . '/src/addons/*'; + foreach (glob($globPattern) as $rootPath) { + $rootNamespace = basename($rootPath); + $autoLoader->setPsr4($rootNamespace . '\\', $rootPath); + } + } + + spl_autoload_register(array($this, 'autoload'), true, true); + + $this->_setup = true; + } + + public function autoload($class) + { + if (class_exists($class, false) || interface_exists($class, false)) { + return true; + } + + if ($class == 'utf8_entity_decoder') { + return false; + } + + if (substr($class, 0, 5) == 'XFCP_') { + return false; + } + + file_put_contents('/var/www/html/xenforo/internal_data/autoload.log', $class . "\n", FILE_APPEND); + switch ($class) { + case 'XF\Extension': + $original = file_get_contents('/var/www/html/xenforo/src/XF/Extension.php'); + $renamed = str_replace('class Extension', 'class _Extension', $original); + eval(substr($renamed, strlen('setupAutoloader(); + } + + public static function locateCached($fullPath) + { + $key = basename($fullPath) . md5($fullPath); + $cached = apcu_fetch($key); + $located = null; + $success = false; + if (is_array($cached) + && $cached['fullPath'] === $fullPath) { + $located = $cached['located']; + } + + if (empty($located)) { + $located = static::locate($fullPath, $success); + } + + if ($success) { + $cacheEntry = array( + 'fullPath' => $fullPath, + 'located' => $located, + ); + + apcu_store($key, $cacheEntry); + } + + return $located; + } + + public static function locate($fullPath, &$success = null) + { + if (file_exists($fullPath)) { + $success = true; + return $fullPath; + } + + list($xenforoDir, $addOnPaths) = static::getLocatePaths(); + $shortened = preg_replace( + '#^' . preg_quote($xenforoDir, '#') . '#', + '', + $fullPath + ); + + foreach ($addOnPaths as $addOnPath) { + $candidatePath = $addOnPath . $shortened; + if (file_exists($candidatePath)) { + $success = true; + return $candidatePath; + } + } + + return $fullPath; + } + + public static function getLocatePaths() + { + static $xenforoDir = null; + static $addOnPaths = null; + + if ($addOnPaths === null) { + $routerPhp = $_SERVER['DEVHELPER_ROUTER_PHP']; + $routerPhpDir = dirname($routerPhp); + $xenforoDir = sprintf('%s/xenforo', $routerPhpDir); + $addOnPaths = array(); + + $txtPath = sprintf('%s/internal_data/addons2.txt', $xenforoDir); + $lines = array(); + if (file_exists($txtPath)) { + $lines = file($txtPath); + } + $prefix = 'addons'; + $prefixLength = strlen($prefix); + + foreach ($lines as $line) { + $line = trim($line); + if (strlen($line) === 0) { + continue; + } + + if (substr($line, 0, $prefixLength) !== $prefix) { + continue; + } + + $addOnPaths[] = sprintf('%s/%s', $routerPhpDir, $line); + } + } + + return array($xenforoDir, $addOnPaths); + } +} diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php new file mode 100644 index 0000000..477f45e --- /dev/null +++ b/src/addons/DevHelper/StreamWrapper.php @@ -0,0 +1,327 @@ +_dirHandle)) { + return false; + } + + closedir($this->_dirHandle); + + $this->_dirPath = null; + $this->_dirHandle = null; + + return true; + } + + /** + * Open directory handle + * + * @param string $path + * @param int $options + * @return bool + */ + public function dir_opendir($path, $options) + { + $located = $this->locate($path); + if (!file_exists($located)) { + return false; + } + + $this->_dirPath = $path; + $this->_dirHandle = opendir($located); + + return true; + } + + /** + * Read entry from directory handle + * + * @return string|false + */ + public function dir_readdir() + { + if (empty($this->_dirHandle)) { + return false; + } + + return readdir($this->_dirHandle); + } + + /** + * Rewind directory handle + * + * @return bool + */ + public function dir_rewinddir() + { + if (empty($this->_dirHandle)) { + return false; + } + + return rewinddir($this->_dirHandle); + } + + /** + * Create a directory + * + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + public function mkdir($path, $mode, $options) + { + $located = $this->locate($path); + if (!file_exists($located)) { + $locatedDir = $this->locate(dirname($path)); + if (is_dir($locatedDir)) { + $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); + } + } + + return mkdir($located, $mode, $options); + } + + /** + * Retrieve the under laying resource + * + * @param int $castAs + * @return resource + */ + public function stream_cast($castAs) + { + if (empty($this->_streamHandle)) { + return null; + } + + return $this->_streamHandle; + } + + /** + * Close an resource + */ + public function stream_close() + { + if (empty($this->_streamHandle)) { + return; + } + + fclose($this->_streamHandle); + + $this->_streamPath = null; + $this->_streamHandle = null; + } + + /** + * Tests for end-of-file on a file pointer + * + * @return bool + */ + public function stream_eof() + { + if (empty($this->_streamHandle)) { + return true; + } + + return feof($this->_streamHandle); + } + + /** + * Advisory file locking + * + * @param $operation + * @return bool + */ + public function stream_lock($operation) + { + if (empty($this->_streamHandle)) { + return false; + } + + return flock($this->_streamHandle, $operation); + } + + /** + * Change stream metadata + * + * @param string $path + * @param int $option + * @param mixed $value + * @return bool + */ + public function stream_metadata($path, $option, $value) + { + switch ($option) { + case STREAM_META_ACCESS: + $located = $this->locate($path); + return chmod($located, $value); + } + + return false; + } + + /** + * Opens file or URL + * + * @param string $path + * @param string $mode + * @param int $options + * @param string &$openedPath + * @return bool + */ + public function stream_open($path, $mode, $options, &$openedPath) + { + $needCreate = false; + if (strpos($mode, 'c') !== false) { + // modes: c, c+ + $needCreate = true; + } elseif (strpos($mode, 'a') !== false + || strpos($mode, '+') !== false + ) { + // modes: r+, w+, a, a+, x+ + $needCreate = true; + } elseif (strpos($mode, 'w') !== false + || strpos($mode, 'x') !== false + ) { + // modes: w, x + $needCreate = true; + } + + $located = $this->locate($path); + if ($needCreate && !file_exists($located)) { + $locatedDir = $this->locate(dirname($path)); + if (is_dir($locatedDir)) { + $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); + } + } + + $this->_streamPath = $path; + $this->_streamHandle = fopen($located, $mode); + + return true; + } + + /** + * Read from stream + * + * @param int $count + * @return string + */ + public function stream_read($count) + { + if (empty($this->_streamHandle)) { + return ''; + } + + return fread($this->_streamHandle, $count); + } + + public function stream_seek($offset, $whence = SEEK_SET) + { + if (empty($this->_streamHandle)) { + return false; + } + + return fseek($this->_streamHandle, $offset, $whence); + } + + /** + * Retrieve information about a file resource + * + * @return array|false + */ + public function stream_stat() + { + if (empty($this->_streamHandle)) { + return false; + } + + return fstat($this->_streamHandle); + } + + /** + * Write to stream + * + * @param string $data + * @return int + */ + public function stream_write($data) + { + if (empty($this->_streamHandle)) { + return 0; + } + + $written = fwrite($this->_streamHandle, $data); + + return $written; + } + + /** + * Delete a file + * + * @param string $path + * @return bool + */ + public function unlink($path) + { + $located = $this->locate($path); + if (!file_exists($located)) { + return false; + } + + return unlink($located); + } + + /** + * Retrieve information about a file + * + * @param string $path + * @param int $flags + * @return array|false + */ + public function url_stat($path, $flags) + { + $located = $this->locate($path); + if (!file_exists($located)) { + return false; + } + + return stat($located); + } + + /** + * @param string $path + * @return string + * @throws \Exception + */ + private function locate($path) + { + $protocolLength = strlen(static::PROTOCOL); + if (substr($path, 0, $protocolLength) !== static::PROTOCOL) { + throw new \Exception('Unrecognized path ' . $path); + } + + $pathWithoutProtocol = substr($path, $protocolLength + 3); + list($xenforoDir,) = Router::getLocatePaths(); + $pathFromRoot = $xenforoDir . DIRECTORY_SEPARATOR . $pathWithoutProtocol; + + return Router::locateCached($pathFromRoot); + } +} \ No newline at end of file diff --git a/src/addons/DevHelper/XF/AddOn/Manager.php b/src/addons/DevHelper/XF/AddOn/Manager.php new file mode 100644 index 0000000..27892fd --- /dev/null +++ b/src/addons/DevHelper/XF/AddOn/Manager.php @@ -0,0 +1,73 @@ +jsonInfo)) { + $skip = false; + } + + $available = parent::getAllJsonInfo(); + + if (!$skip) { + $addOnIds = $this->DevHelper_getAvailableAddOnIds(); + foreach ($addOnIds as $addOnId) { + $available[$addOnId] = $this->getAddOnJsonInfo($addOnId); + } + + $this->jsonInfo = $available; + } + + return $available; + } + + public function getAddOnPath($addOnId) + { + $addOnPath = parent::getAddOnPath($addOnId); + return Router::locateCached($addOnPath); + } + + private function DevHelper_getAvailableAddOnIds() + { + $addOnIds = []; + + list(, $addOnPaths) = Router::getLocatePaths(); + + foreach ($addOnPaths as $addOnPath) { + foreach (new \DirectoryIterator($addOnPath . '/src/addons') as $entry) { + if (!$this->isValidDir($entry)) { + continue; + } + + if ($this->isDirAddOnRoot($entry)) { + $addOnIds[] = $entry->getBasename(); + } else { + $vendorPrefix = $entry->getBasename(); + foreach (new \DirectoryIterator($entry->getPathname()) as $addOnDir) { + if (!$this->isValidDir($addOnDir)) { + continue; + } + + if ($this->isDirAddOnRoot($addOnDir)) { + $addOnIds[] = "$vendorPrefix/{$addOnDir->getBasename()}"; + } + } + } + } + } + + return $addOnIds; + } +} + +if (false) { + class XFCP_Manager extends \XF\AddOn\Manager + { + } +} diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php new file mode 100644 index 0000000..5965bcb --- /dev/null +++ b/src/addons/DevHelper/XF/Extension.php @@ -0,0 +1,28 @@ +addClassExtension($class, 'DevHelper\\' . $class); + } + } + + public function extendClass($class, $fakeBaseClass = null) + { + return parent::extendClass($class, $fakeBaseClass); + } +} diff --git a/src/addons/DevHelper/XF/XF.php b/src/addons/DevHelper/XF/XF.php new file mode 100644 index 0000000..76c30eb --- /dev/null +++ b/src/addons/DevHelper/XF/XF.php @@ -0,0 +1,11 @@ + Date: Wed, 23 Aug 2017 14:24:35 +0700 Subject: [PATCH 002/118] Add support for cmd.php --- cmd.php | 4 ++++ src/addons/DevHelper/.gitignore | 1 + src/addons/DevHelper/Router.php | 18 +++++++++++------- src/addons/DevHelper/addon.json | 17 +++++++++++++---- 4 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 cmd.php create mode 100644 src/addons/DevHelper/.gitignore diff --git a/cmd.php b/cmd.php new file mode 100644 index 0000000..7478b65 --- /dev/null +++ b/cmd.php @@ -0,0 +1,4 @@ + Date: Wed, 23 Aug 2017 15:24:36 +0700 Subject: [PATCH 003/118] Add support for xf-addon:build-release --- src/addons/DevHelper/.gitignore | 2 + src/addons/DevHelper/StreamWrapper.php | 37 +++++--- src/addons/DevHelper/XF/Extension.php | 3 +- .../XF/Service/AddOn/ReleaseBuilder.php | 89 +++++++++++++++++++ 4 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php diff --git a/src/addons/DevHelper/.gitignore b/src/addons/DevHelper/.gitignore index ba65b13..038757a 100644 --- a/src/addons/DevHelper/.gitignore +++ b/src/addons/DevHelper/.gitignore @@ -1 +1,3 @@ /_build/ +/_output/ +/_releases/ diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php index 477f45e..5e94f12 100644 --- a/src/addons/DevHelper/StreamWrapper.php +++ b/src/addons/DevHelper/StreamWrapper.php @@ -39,7 +39,7 @@ public function dir_closedir() */ public function dir_opendir($path, $options) { - $located = $this->locate($path); + $located = static::locate($path); if (!file_exists($located)) { return false; } @@ -88,9 +88,9 @@ public function dir_rewinddir() */ public function mkdir($path, $mode, $options) { - $located = $this->locate($path); + $located = static::locate($path); if (!file_exists($located)) { - $locatedDir = $this->locate(dirname($path)); + $locatedDir = static::locate(dirname($path)); if (is_dir($locatedDir)) { $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); } @@ -99,6 +99,21 @@ public function mkdir($path, $mode, $options) return mkdir($located, $mode, $options); } + /** + * @param string $path + * @param int $options + * @return bool + */ + public function rmdir($path, $options) + { + $located = static::locate($path); + if (!file_exists($located)) { + return false; + } + + return rmdir($path); + } + /** * Retrieve the under laying resource * @@ -170,7 +185,7 @@ public function stream_metadata($path, $option, $value) { switch ($option) { case STREAM_META_ACCESS: - $located = $this->locate($path); + $located = static::locate($path); return chmod($located, $value); } @@ -204,9 +219,9 @@ public function stream_open($path, $mode, $options, &$openedPath) $needCreate = true; } - $located = $this->locate($path); + $located = static::locate($path); if ($needCreate && !file_exists($located)) { - $locatedDir = $this->locate(dirname($path)); + $locatedDir = static::locate(dirname($path)); if (is_dir($locatedDir)) { $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); } @@ -281,7 +296,7 @@ public function stream_write($data) */ public function unlink($path) { - $located = $this->locate($path); + $located = static::locate($path); if (!file_exists($located)) { return false; } @@ -298,12 +313,14 @@ public function unlink($path) */ public function url_stat($path, $flags) { - $located = $this->locate($path); + $located = static::locate($path); if (!file_exists($located)) { return false; } - return stat($located); + $stat = stat($located); + + return $stat; } /** @@ -311,7 +328,7 @@ public function url_stat($path, $flags) * @return string * @throws \Exception */ - private function locate($path) + public static function locate($path) { $protocolLength = strlen(static::PROTOCOL); if (substr($path, 0, $protocolLength) !== static::PROTOCOL) { diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php index 5965bcb..cefd4d3 100644 --- a/src/addons/DevHelper/XF/Extension.php +++ b/src/addons/DevHelper/XF/Extension.php @@ -14,7 +14,8 @@ public function __construct(array $listeners = [], array $classExtensions = []) XF::setSourceDirectory(StreamWrapper::PROTOCOL . '://src'); $classes = [ - 'XF\AddOn\Manager' + 'XF\AddOn\Manager', + 'XF\Service\AddOn\ReleaseBuilder', ]; foreach ($classes as $class) { $this->addClassExtension($class, 'DevHelper\\' . $class); diff --git a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php new file mode 100644 index 0000000..6c0dfcc --- /dev/null +++ b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php @@ -0,0 +1,89 @@ +buildRoot = '/var/www/html/xenforo/internal_data/builds/' . $this->addOn->getAddOnId(); + } + + protected function prepareFilesToCopy() + { + parent::prepareFilesToCopy(); + + $srcUptoNamespace = $this->addOnRoot; + $srcUptoNamespaceLocated = StreamWrapper::locate($srcUptoNamespace); + $repoPath = preg_replace('#/src/addons.+$#', '', $srcUptoNamespaceLocated); + $ds = DIRECTORY_SEPARATOR; + + $dirPaths = []; + foreach (new \DirectoryIterator($repoPath) as $dirCandidate) { + if (!$dirCandidate->isDir() + || $dirCandidate->isDot()) { + continue; + } + + $skip = false; + $basename = $dirCandidate->getBasename(); + switch ($basename) { + case '.git': + case 'addons': + case 'dev-scripts': + case 'library': + case 'src': + case 'xenforo': + $skip = true; + break; + } + if ($skip) { + continue; + } + + $dirPaths[] = $dirCandidate->getPathname(); + } + + foreach ($dirPaths as $dirPath) { + $dirStandardized = $this->standardizePath($repoPath, $dirPath); + + $filesIterator = $this->getFileIterator($dirPath); + foreach ($filesIterator AS $file) { + if ($file->isDir()) { + continue; + } + + $fileStandardized = $this->standardizePath($dirPath, $file->getPathname()); + $destination = $this->uploadRoot . $ds . $dirStandardized . $ds . $fileStandardized; + File::copyFile($file->getPathname(), $destination, false); + } + } + } + + public function finalizeRelease() + { + $addOnId = $this->addOn->prepareAddOnIdForFilename(); + $versionString = $this->addOn->prepareVersionForFilename(); + $releasePath = sprintf( + '/var/www/html/xenforo/internal_data/releases/%1$s/%1$s-%2$s.zip', + $addOnId, + $versionString + ); + + File::createDirectory(dirname($releasePath), false); + File::renameFile($this->tempFile, $releasePath, false); + + // intentionally do not call parent + } +} + +if (false) { + class XFCP_ReleaseBuilder extends \XF\Service\AddOn\ReleaseBuilder + { + } +} \ No newline at end of file From 3a93ab32fa095bcca9812293e14aa68eeac72bd8 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 23 Aug 2017 15:55:13 +0700 Subject: [PATCH 004/118] Fix bug rmdir --- src/addons/DevHelper/StreamWrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php index 5e94f12..20cb91e 100644 --- a/src/addons/DevHelper/StreamWrapper.php +++ b/src/addons/DevHelper/StreamWrapper.php @@ -111,7 +111,7 @@ public function rmdir($path, $options) return false; } - return rmdir($path); + return rmdir($located); } /** From 9d2cfd5889872437344cb5903c85a65fa3b0ae82 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 23 Aug 2017 15:55:46 +0700 Subject: [PATCH 005/118] Improve support for xf-addon:build-release --- src/addons/DevHelper/XF/AddOn/AddOn.php | 24 +++++++++++++++++++ src/addons/DevHelper/XF/AddOn/Manager.php | 9 +++++++ src/addons/DevHelper/XF/Extension.php | 6 +---- .../XF/Service/AddOn/ReleaseBuilder.php | 22 ++++------------- 4 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 src/addons/DevHelper/XF/AddOn/AddOn.php diff --git a/src/addons/DevHelper/XF/AddOn/AddOn.php b/src/addons/DevHelper/XF/AddOn/AddOn.php new file mode 100644 index 0000000..97af710 --- /dev/null +++ b/src/addons/DevHelper/XF/AddOn/AddOn.php @@ -0,0 +1,24 @@ +prepareAddOnIdForFilename(); + $versionString = $this->prepareVersionForFilename(); + /** @noinspection PhpUndefinedFieldInspection */ + $this->buildDir = '/var/www/html/xenforo/internal_data/builds/' . $addOnId . '/' . $versionString; + /** @noinspection PhpUndefinedFieldInspection */ + $this->releasesDir = '/var/www/html/xenforo/internal_data/releases/' . $addOnId; + } +} + +if (false) { + class XFCP_AddOn extends \XF\AddOn\AddOn + { + } +} diff --git a/src/addons/DevHelper/XF/AddOn/Manager.php b/src/addons/DevHelper/XF/AddOn/Manager.php index 27892fd..3d81661 100644 --- a/src/addons/DevHelper/XF/AddOn/Manager.php +++ b/src/addons/DevHelper/XF/AddOn/Manager.php @@ -33,6 +33,15 @@ public function getAddOnPath($addOnId) return Router::locateCached($addOnPath); } + protected function loadAddOnClass($addOnOrId, array $jsonInfo = null) + { + $addOn = parent::loadAddOnClass($addOnOrId, $jsonInfo); + + $class = \XF::app()->extendClass('XF\AddOn\AddOn'); + + return new $class($addOnOrId ?: $addOn->getAddOnId()); + } + private function DevHelper_getAvailableAddOnIds() { $addOnIds = []; diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php index cefd4d3..54d9925 100644 --- a/src/addons/DevHelper/XF/Extension.php +++ b/src/addons/DevHelper/XF/Extension.php @@ -14,6 +14,7 @@ public function __construct(array $listeners = [], array $classExtensions = []) XF::setSourceDirectory(StreamWrapper::PROTOCOL . '://src'); $classes = [ + 'XF\AddOn\AddOn', 'XF\AddOn\Manager', 'XF\Service\AddOn\ReleaseBuilder', ]; @@ -21,9 +22,4 @@ public function __construct(array $listeners = [], array $classExtensions = []) $this->addClassExtension($class, 'DevHelper\\' . $class); } } - - public function extendClass($class, $fakeBaseClass = null) - { - return parent::extendClass($class, $fakeBaseClass); - } } diff --git a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php index 6c0dfcc..ae1e25d 100644 --- a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php +++ b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php @@ -7,13 +7,6 @@ class ReleaseBuilder extends XFCP_ReleaseBuilder { - protected function prepareDirectories() - { - parent::prepareDirectories(); - - $this->buildRoot = '/var/www/html/xenforo/internal_data/builds/' . $this->addOn->getAddOnId(); - } - protected function prepareFilesToCopy() { parent::prepareFilesToCopy(); @@ -67,18 +60,11 @@ protected function prepareFilesToCopy() public function finalizeRelease() { - $addOnId = $this->addOn->prepareAddOnIdForFilename(); - $versionString = $this->addOn->prepareVersionForFilename(); - $releasePath = sprintf( - '/var/www/html/xenforo/internal_data/releases/%1$s/%1$s-%2$s.zip', - $addOnId, - $versionString - ); - - File::createDirectory(dirname($releasePath), false); - File::renameFile($this->tempFile, $releasePath, false); + $oopsPath = $this->buildRoot . '/oops'; + File::createDirectory($oopsPath, false); + $this->buildRoot = $oopsPath; - // intentionally do not call parent + parent::finalizeRelease(); } } From 029fa70e5ab19388bab30f82f3c45f7c4eeb0b87 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 30 Aug 2017 13:26:56 +0700 Subject: [PATCH 006/118] Improve support for locate --- dev-scripts/docker/find-addons2.sh | 2 +- src/addons/DevHelper/Router.php | 32 +++++++++++--- src/addons/DevHelper/StreamWrapper.php | 36 +++++++++++++++- src/addons/DevHelper/XF/AddOn/Manager.php | 51 +---------------------- 4 files changed, 63 insertions(+), 58 deletions(-) diff --git a/dev-scripts/docker/find-addons2.sh b/dev-scripts/docker/find-addons2.sh index 70c7b30..b28adb9 100644 --- a/dev-scripts/docker/find-addons2.sh +++ b/dev-scripts/docker/find-addons2.sh @@ -6,5 +6,5 @@ cd /var/www/html/ { \ echo "# Generated by $0"; \ - find addons/ -maxdepth 5 -name src -type d | grep -v .git | sed 's#/src##'; \ + find addons/ -maxdepth 5 -name .git -type d | sed 's#/.git##'; \ } > ./xenforo/internal_data/addons2.txt diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php index c197250..6a20901 100644 --- a/src/addons/DevHelper/Router.php +++ b/src/addons/DevHelper/Router.php @@ -116,11 +116,23 @@ public static function locate($fullPath, &$success = null) $fullPath ); - foreach ($addOnPaths as $addOnPath) { - $candidatePath = $addOnPath . $shortened; - if (file_exists($candidatePath)) { - $success = true; - return $candidatePath; + foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { + $candidatePaths = []; + + if (strpos($shortened, '/src/addons/') === 0) { + $relativeRegex = '#^.+?' . preg_quote($addOnPathSuffix, '#') . '#'; + $relativePath = preg_replace($relativeRegex, '', $shortened, -1, $count); + if ($count === 1) { + $candidatePaths[] = $addOnPath . $shortened; + $candidatePaths[] = $addOnPath . $relativePath; + } + } + + foreach ($candidatePaths as $candidatePath) { + if (file_exists($candidatePath)) { + $success = true; + return $candidatePath; + } } } @@ -156,10 +168,18 @@ public static function getLocatePaths() continue; } - $addOnPaths[] = sprintf('%s/%s', $routerPhpDir, $line); + $addOnPath = sprintf('%s/%s', $routerPhpDir, $line); + $addOnPathSuffix = trim(preg_replace('#^.+addons#', '', $addOnPath), '/'); + $addOnPaths[$addOnPathSuffix] = $addOnPath; } } return array($xenforoDir, $addOnPaths); } + + public static function locateReset() + { + apcu_clear_cache(); + exec('/usr/local/bin/find-addons2.sh'); + } } diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php index 20cb91e..76fe106 100644 --- a/src/addons/DevHelper/StreamWrapper.php +++ b/src/addons/DevHelper/StreamWrapper.php @@ -8,6 +8,7 @@ class StreamWrapper private $_dirPath; private $_dirHandle; + private $_dirSecondHandle; private $_streamPath; private $_streamHandle; @@ -24,8 +25,13 @@ public function dir_closedir() closedir($this->_dirHandle); + if (!empty($this->_dirSecondHandle)) { + closedir($this->_dirSecondHandle); + } + $this->_dirPath = null; $this->_dirHandle = null; + $this->_dirSecondHandle = null; return true; } @@ -47,6 +53,10 @@ public function dir_opendir($path, $options) $this->_dirPath = $path; $this->_dirHandle = opendir($located); + if ($located === '/var/www/html/xenforo/src/addons') { + $this->_dirSecondHandle = opendir('/var/www/html/addons'); + } + return true; } @@ -61,7 +71,22 @@ public function dir_readdir() return false; } - return readdir($this->_dirHandle); + $read = readdir($this->_dirHandle); + + if ($read === false && !empty($this->_dirSecondHandle)) { + while (true) { + $secondRead = readdir($this->_dirSecondHandle); + switch ($secondRead) { + case '.': + case '..': + continue; + } + + return $secondRead; + } + } + + return $read; } /** @@ -75,7 +100,13 @@ public function dir_rewinddir() return false; } - return rewinddir($this->_dirHandle); + $bool = rewinddir($this->_dirHandle); + + if (!empty($this->_dirSecondHandle)) { + rewind($this->_dirSecondHandle); + } + + return $bool; } /** @@ -314,6 +345,7 @@ public function unlink($path) public function url_stat($path, $flags) { $located = static::locate($path); + if (!file_exists($located)) { return false; } diff --git a/src/addons/DevHelper/XF/AddOn/Manager.php b/src/addons/DevHelper/XF/AddOn/Manager.php index 3d81661..3cf7191 100644 --- a/src/addons/DevHelper/XF/AddOn/Manager.php +++ b/src/addons/DevHelper/XF/AddOn/Manager.php @@ -8,23 +8,8 @@ class Manager extends XFCP_Manager { protected function getAllJsonInfo() { - $skip = true; - if (!is_array($this->jsonInfo)) { - $skip = false; - } - - $available = parent::getAllJsonInfo(); - - if (!$skip) { - $addOnIds = $this->DevHelper_getAvailableAddOnIds(); - foreach ($addOnIds as $addOnId) { - $available[$addOnId] = $this->getAddOnJsonInfo($addOnId); - } - - $this->jsonInfo = $available; - } - - return $available; + Router::locateReset(); + return parent::getAllJsonInfo(); } public function getAddOnPath($addOnId) @@ -41,38 +26,6 @@ protected function loadAddOnClass($addOnOrId, array $jsonInfo = null) return new $class($addOnOrId ?: $addOn->getAddOnId()); } - - private function DevHelper_getAvailableAddOnIds() - { - $addOnIds = []; - - list(, $addOnPaths) = Router::getLocatePaths(); - - foreach ($addOnPaths as $addOnPath) { - foreach (new \DirectoryIterator($addOnPath . '/src/addons') as $entry) { - if (!$this->isValidDir($entry)) { - continue; - } - - if ($this->isDirAddOnRoot($entry)) { - $addOnIds[] = $entry->getBasename(); - } else { - $vendorPrefix = $entry->getBasename(); - foreach (new \DirectoryIterator($entry->getPathname()) as $addOnDir) { - if (!$this->isValidDir($addOnDir)) { - continue; - } - - if ($this->isDirAddOnRoot($addOnDir)) { - $addOnIds[] = "$vendorPrefix/{$addOnDir->getBasename()}"; - } - } - } - } - } - - return $addOnIds; - } } if (false) { From 1918c2dd20738074fff8ae97637f6ddda1ae572a Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 30 Aug 2017 13:35:03 +0700 Subject: [PATCH 007/118] Improve support for locate (continue from 029fa70e) --- src/addons/DevHelper/Autoloader.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/addons/DevHelper/Autoloader.php b/src/addons/DevHelper/Autoloader.php index c8d2d3f..4716f7a 100644 --- a/src/addons/DevHelper/Autoloader.php +++ b/src/addons/DevHelper/Autoloader.php @@ -23,12 +23,18 @@ public function setupAutoloader() $autoLoader = require('/var/www/html/xenforo/src/vendor/autoload.php'); list(, $addOnPaths) = Router::getLocatePaths(); - foreach ($addOnPaths as $addOnPath) { + foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { $globPattern = $addOnPath . '/src/addons/*'; - foreach (glob($globPattern) as $rootPath) { + $rootPaths = glob($globPattern); + foreach ($rootPaths as $rootPath) { $rootNamespace = basename($rootPath); $autoLoader->setPsr4($rootNamespace . '\\', $rootPath); } + + if (count($rootPaths) === 0) { + $rootNamespace = str_replace(DIRECTORY_SEPARATOR, '\\', $addOnPathSuffix); + $autoLoader->setPsr4($rootNamespace . '\\', $addOnPath); + } } spl_autoload_register(array($this, 'autoload'), true, true); From 6a60923fa352e0f41629ce43fee716fd63562df9 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 7 Sep 2017 00:04:21 +0700 Subject: [PATCH 008/118] Add addons2.txt regeneration --- src/addons/DevHelper/Router.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php index 6a20901..8deacf2 100644 --- a/src/addons/DevHelper/Router.php +++ b/src/addons/DevHelper/Router.php @@ -151,10 +151,10 @@ public static function getLocatePaths() $addOnPaths = array(); $txtPath = sprintf('%s/internal_data/addons2.txt', $xenforoDir); - $lines = array(); - if (file_exists($txtPath)) { - $lines = file($txtPath); + if (!file_exists($txtPath)) { + exec('/usr/local/bin/find-addons2.sh'); } + $lines = file($txtPath); $prefix = 'addons'; $prefixLength = strlen($prefix); From 391000596e1e418beb3cfc45a06ca83d50bff721 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 7 Sep 2017 00:04:48 +0700 Subject: [PATCH 009/118] Simplify add-on release builder --- .../XF/Service/AddOn/ReleaseBuilder.php | 60 +++---------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php index ae1e25d..671869b 100644 --- a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php +++ b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php @@ -7,57 +7,6 @@ class ReleaseBuilder extends XFCP_ReleaseBuilder { - protected function prepareFilesToCopy() - { - parent::prepareFilesToCopy(); - - $srcUptoNamespace = $this->addOnRoot; - $srcUptoNamespaceLocated = StreamWrapper::locate($srcUptoNamespace); - $repoPath = preg_replace('#/src/addons.+$#', '', $srcUptoNamespaceLocated); - $ds = DIRECTORY_SEPARATOR; - - $dirPaths = []; - foreach (new \DirectoryIterator($repoPath) as $dirCandidate) { - if (!$dirCandidate->isDir() - || $dirCandidate->isDot()) { - continue; - } - - $skip = false; - $basename = $dirCandidate->getBasename(); - switch ($basename) { - case '.git': - case 'addons': - case 'dev-scripts': - case 'library': - case 'src': - case 'xenforo': - $skip = true; - break; - } - if ($skip) { - continue; - } - - $dirPaths[] = $dirCandidate->getPathname(); - } - - foreach ($dirPaths as $dirPath) { - $dirStandardized = $this->standardizePath($repoPath, $dirPath); - - $filesIterator = $this->getFileIterator($dirPath); - foreach ($filesIterator AS $file) { - if ($file->isDir()) { - continue; - } - - $fileStandardized = $this->standardizePath($dirPath, $file->getPathname()); - $destination = $this->uploadRoot . $ds . $dirStandardized . $ds . $fileStandardized; - File::copyFile($file->getPathname(), $destination, false); - } - } - } - public function finalizeRelease() { $oopsPath = $this->buildRoot . '/oops'; @@ -66,6 +15,15 @@ public function finalizeRelease() parent::finalizeRelease(); } + + protected function getExcludedDirectories() + { + $dirs = parent::getExcludedDirectories(); + + $dirs[] = '.git'; + + return $dirs; + } } if (false) { From e8421b3d71d30cb71a6724cfc1e90a86c96ae332 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 21 Sep 2017 19:01:17 +0700 Subject: [PATCH 010/118] Fix http client issue because of our stream wrapper --- src/addons/DevHelper/Listener.php | 16 ++++++++++++++++ src/addons/DevHelper/XF/Extension.php | 12 ++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/addons/DevHelper/Listener.php diff --git a/src/addons/DevHelper/Listener.php b/src/addons/DevHelper/Listener.php new file mode 100644 index 0000000..303b7db --- /dev/null +++ b/src/addons/DevHelper/Listener.php @@ -0,0 +1,16 @@ +setDefaultOption('verify', '/var/www/html/xenforo/src/XF/Http/ca-bundle.crt'); + } +} \ No newline at end of file diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php index 54d9925..f81ddcc 100644 --- a/src/addons/DevHelper/XF/Extension.php +++ b/src/addons/DevHelper/XF/Extension.php @@ -6,6 +6,16 @@ class Extension extends \XF\_Extension { + /** + * Extension constructor. + * @param array $listeners + * @param array $classExtensions + * + * @see \DevHelper\Listener::httpClientConfig() + * @see \DevHelper\XF\AddOn\AddOn + * @see \DevHelper\XF\AddOn\Manager + * @see \DevHelper\XF\Service\AddOn\ReleaseBuilder + */ public function __construct(array $listeners = [], array $classExtensions = []) { parent::__construct($listeners, $classExtensions); @@ -13,6 +23,8 @@ public function __construct(array $listeners = [], array $classExtensions = []) stream_wrapper_register(StreamWrapper::PROTOCOL, StreamWrapper::class); XF::setSourceDirectory(StreamWrapper::PROTOCOL . '://src'); + $this->addListener('http_client_config', ['DevHelper\\Listener', 'httpClientConfig']); + $classes = [ 'XF\AddOn\AddOn', 'XF\AddOn\Manager', From 84042380095b817ce8bf59f3c4b15d474b3e6935 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 21 Sep 2017 19:01:31 +0700 Subject: [PATCH 011/118] Improve Router implementation --- src/addons/DevHelper/Router.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php index 8deacf2..c8ede29 100644 --- a/src/addons/DevHelper/Router.php +++ b/src/addons/DevHelper/Router.php @@ -4,6 +4,8 @@ class Router { + const PATH_SLASH_SRC_ADDONS_SLASH = '/src/addons/'; + public static function route($routerPhpPath) { $_SERVER['DEVHELPER_ROUTER_PHP'] = $routerPhpPath; @@ -119,12 +121,16 @@ public static function locate($fullPath, &$success = null) foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { $candidatePaths = []; - if (strpos($shortened, '/src/addons/') === 0) { - $relativeRegex = '#^.+?' . preg_quote($addOnPathSuffix, '#') . '#'; - $relativePath = preg_replace($relativeRegex, '', $shortened, -1, $count); - if ($count === 1) { - $candidatePaths[] = $addOnPath . $shortened; - $candidatePaths[] = $addOnPath . $relativePath; + if (strpos($shortened, static::PATH_SLASH_SRC_ADDONS_SLASH) === 0) { + $relativePath = substr($shortened, strlen(static::PATH_SLASH_SRC_ADDONS_SLASH)); + if (strpos($relativePath, $addOnPathSuffix) === 0) { + $candidatePaths[] = $addOnPath . '/' . substr($relativePath, strlen($addOnPathSuffix)); + } elseif (strpos($addOnPathSuffix, $relativePath) === 0) { + $parentPathSuffix = dirname($addOnPathSuffix); + $parentPath = dirname($addOnPath); + if (strpos($relativePath, $parentPathSuffix) === 0) { + $candidatePaths[] = $parentPath; + } } } From c778cbe13287dbb274601e999ff991fd9d782eec Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 26 Oct 2017 00:03:43 +0700 Subject: [PATCH 012/118] Clean up --- .gitignore | 13 - addons/.gitkeep | 0 aptana.xml | 215 - .../Lib/CodeMirror/addon/dialog/dialog.css | 32 - .../Lib/CodeMirror/addon/dialog/dialog.js | 157 - .../addon/scroll/annotatescrollbar.js | 122 - .../CodeMirror/addon/scroll/scrollpastend.js | 48 - .../addon/scroll/simplescrollbars.css | 66 - .../addon/scroll/simplescrollbars.js | 152 - .../CodeMirror/addon/search/jump-to-line.js | 49 - .../addon/search/match-highlighter.js | 165 - .../addon/search/matchesonscrollbar.css | 8 - .../addon/search/matchesonscrollbar.js | 97 - .../Lib/CodeMirror/addon/search/search.js | 252 - .../CodeMirror/addon/search/searchcursor.js | 289 - .../Lib/CodeMirror/lib/codemirror.css | 340 - js/DevHelper/Lib/CodeMirror/lib/codemirror.js | 9479 ----------------- js/DevHelper/Lib/CodeMirror/mode/css/css.js | 830 -- js/DevHelper/Lib/CodeMirror/mode/css/gss.html | 103 - .../Lib/CodeMirror/mode/css/gss_test.js | 17 - .../Lib/CodeMirror/mode/css/index.html | 75 - .../Lib/CodeMirror/mode/css/less.html | 152 - .../Lib/CodeMirror/mode/css/less_test.js | 54 - .../Lib/CodeMirror/mode/css/scss.html | 157 - .../Lib/CodeMirror/mode/css/scss_test.js | 110 - js/DevHelper/Lib/CodeMirror/mode/css/test.js | 200 - .../mode/htmlembedded/htmlembedded.js | 28 - .../CodeMirror/mode/htmlembedded/index.html | 60 - .../CodeMirror/mode/htmlmixed/htmlmixed.js | 152 - .../Lib/CodeMirror/mode/htmlmixed/index.html | 100 - .../Lib/CodeMirror/mode/javascript/index.html | 114 - .../CodeMirror/mode/javascript/javascript.js | 818 -- .../CodeMirror/mode/javascript/json-ld.html | 72 - .../Lib/CodeMirror/mode/javascript/test.js | 379 - .../mode/javascript/typescript.html | 61 - .../Lib/CodeMirror/mode/xml/index.html | 61 - js/DevHelper/Lib/CodeMirror/mode/xml/test.js | 51 - js/DevHelper/Lib/CodeMirror/mode/xml/xml.js | 394 - js/DevHelper/full/template_edit.js | 132 - library/DevHelper/Autoloader.php | 175 - library/DevHelper/Config/Base.php | 415 - library/DevHelper/ControllerHelper/AddOn.php | 65 - library/DevHelper/Generator/Code/Common.php | 233 - .../Generator/Code/ControllerAdmin.php | 724 -- .../DevHelper/Generator/Code/DataWriter.php | 395 - .../DevHelper/Generator/Code/Installer.php | 133 - library/DevHelper/Generator/Code/Listener.php | 111 - library/DevHelper/Generator/Code/Model.php | 674 -- .../Generator/Code/RoutePrefixAdmin.php | 131 - .../Generator/Code/XenForoConfig.php | 55 - library/DevHelper/Generator/Db.php | 360 - library/DevHelper/Generator/File.php | 747 -- library/DevHelper/Generator/Phrase.php | 64 - library/DevHelper/Generator/Template.php | 70 - library/DevHelper/Generator/phpcs.xml | 28 - library/DevHelper/Helper/File.php | 34 - library/DevHelper/Helper/Js.php | 83 - library/DevHelper/Helper/Php.php | 107 - library/DevHelper/Helper/Phrase.php | 149 - library/DevHelper/Helper/ShippableHelper.php | 85 - .../Helper/ShippableHelper/Crypt.php | 153 - .../Helper/ShippableHelper/DateTime.php | 99 - .../DevHelper/Helper/ShippableHelper/Html.php | 399 - .../DevHelper/Helper/ShippableHelper/Http.php | 110 - .../Helper/ShippableHelper/Image.php | 77 - .../Helper/ShippableHelper/ImageCore.php | 330 - .../Helper/ShippableHelper/ImageSize.php | 542 - .../DevHelper/Helper/ShippableHelper/S3.php | 227 - .../Helper/ShippableHelper/String.php | 26 - .../Helper/ShippableHelper/TempFile.php | 213 - .../Helper/ShippableHelper/Updater.php | 195 - .../Helper/ShippableHelper/UpdaterCore.php | 794 -- library/DevHelper/Helper/Template.php | 56 - library/DevHelper/Helper/Xfcp.php | 96 - library/DevHelper/Installer.php | 107 - library/DevHelper/Listener.php | 175 - library/DevHelper/Model/Config.php | 48 - library/DevHelper/Router.php | 154 - .../DevHelper/ViewAdmin/AddOn/DataManager.php | 18 - library/DevHelper/XenForo/CodeEvent.php | 113 - .../XenForo/ControllerAdmin/AddOn.php | 387 - .../AdminTemplateModification.php | 21 - .../ControllerAdmin/CodeEventListener.php | 69 - .../XenForo/ControllerAdmin/Home.php | 13 - .../XenForo/ControllerAdmin/Permission.php | 41 - .../XenForo/ControllerAdmin/Phrase.php | 28 - .../XenForo/ControllerAdmin/RoutePrefix.php | 26 - .../XenForo/ControllerAdmin/Template.php | 28 - .../ControllerAdmin/TemplateModification.php | 21 - .../XenForo/ControllerAdmin/Tools.php | 190 - .../XenForo/ControllerHelper/Editor.php | 26 - .../XenForo/ControllerPublic/Forum.php | 43 - .../XenForo/ControllerPublic/Thread.php | 38 - .../DevHelper/XenForo/DataWriter/AddOn.php | 15 - .../XenForo/DataWriter/CodeEventListener.php | 29 - .../DevHelper/XenForo/DataWriter/Template.php | 24 - library/DevHelper/XenForo/Debug.php | 52 - library/DevHelper/XenForo/Model/AddOn.php | 34 - .../XenForo/Route/PrefixAdmin/Templates.php | 22 - .../DevHelper/XenForo/Template/Abstract.php | 31 - .../XenForo/ViewAdmin/AddOn/Upgrade.php | 20 - .../DevHelper/XenForo/ViewRenderer/Json.php | 71 - library/DevHelper/addon-devHelper.xml | 262 - xenforo/.gitkeep | 0 104 files changed, 25865 deletions(-) create mode 100644 addons/.gitkeep delete mode 100644 aptana.xml delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.css delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/scroll/annotatescrollbar.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/scroll/scrollpastend.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.css delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/jump-to-line.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/match-highlighter.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.css delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/search.js delete mode 100644 js/DevHelper/Lib/CodeMirror/addon/search/searchcursor.js delete mode 100644 js/DevHelper/Lib/CodeMirror/lib/codemirror.css delete mode 100644 js/DevHelper/Lib/CodeMirror/lib/codemirror.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/css.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/gss.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/gss_test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/index.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/less.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/less_test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/scss.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/scss_test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/css/test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/htmlembedded/htmlembedded.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/htmlembedded/index.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/htmlmixed/htmlmixed.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/htmlmixed/index.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/javascript/index.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/javascript/javascript.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/javascript/json-ld.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/javascript/test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/javascript/typescript.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/xml/index.html delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/xml/test.js delete mode 100644 js/DevHelper/Lib/CodeMirror/mode/xml/xml.js delete mode 100755 js/DevHelper/full/template_edit.js delete mode 100644 library/DevHelper/Autoloader.php delete mode 100755 library/DevHelper/Config/Base.php delete mode 100644 library/DevHelper/ControllerHelper/AddOn.php delete mode 100755 library/DevHelper/Generator/Code/Common.php delete mode 100755 library/DevHelper/Generator/Code/ControllerAdmin.php delete mode 100755 library/DevHelper/Generator/Code/DataWriter.php delete mode 100755 library/DevHelper/Generator/Code/Installer.php delete mode 100644 library/DevHelper/Generator/Code/Listener.php delete mode 100755 library/DevHelper/Generator/Code/Model.php delete mode 100755 library/DevHelper/Generator/Code/RoutePrefixAdmin.php delete mode 100644 library/DevHelper/Generator/Code/XenForoConfig.php delete mode 100755 library/DevHelper/Generator/Db.php delete mode 100755 library/DevHelper/Generator/File.php delete mode 100755 library/DevHelper/Generator/Phrase.php delete mode 100755 library/DevHelper/Generator/Template.php delete mode 100644 library/DevHelper/Generator/phpcs.xml delete mode 100644 library/DevHelper/Helper/File.php delete mode 100644 library/DevHelper/Helper/Js.php delete mode 100644 library/DevHelper/Helper/Php.php delete mode 100644 library/DevHelper/Helper/Phrase.php delete mode 100644 library/DevHelper/Helper/ShippableHelper.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/Crypt.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/DateTime.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/Html.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/Http.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/Image.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/ImageCore.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/ImageSize.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/S3.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/String.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/TempFile.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/Updater.php delete mode 100644 library/DevHelper/Helper/ShippableHelper/UpdaterCore.php delete mode 100644 library/DevHelper/Helper/Template.php delete mode 100644 library/DevHelper/Helper/Xfcp.php delete mode 100644 library/DevHelper/Installer.php delete mode 100755 library/DevHelper/Listener.php delete mode 100755 library/DevHelper/Model/Config.php delete mode 100644 library/DevHelper/Router.php delete mode 100755 library/DevHelper/ViewAdmin/AddOn/DataManager.php delete mode 100644 library/DevHelper/XenForo/CodeEvent.php delete mode 100755 library/DevHelper/XenForo/ControllerAdmin/AddOn.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/AdminTemplateModification.php delete mode 100755 library/DevHelper/XenForo/ControllerAdmin/CodeEventListener.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/Home.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/Permission.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/Phrase.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/RoutePrefix.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/Template.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/TemplateModification.php delete mode 100644 library/DevHelper/XenForo/ControllerAdmin/Tools.php delete mode 100644 library/DevHelper/XenForo/ControllerHelper/Editor.php delete mode 100644 library/DevHelper/XenForo/ControllerPublic/Forum.php delete mode 100644 library/DevHelper/XenForo/ControllerPublic/Thread.php delete mode 100644 library/DevHelper/XenForo/DataWriter/AddOn.php delete mode 100644 library/DevHelper/XenForo/DataWriter/CodeEventListener.php delete mode 100644 library/DevHelper/XenForo/DataWriter/Template.php delete mode 100644 library/DevHelper/XenForo/Debug.php delete mode 100755 library/DevHelper/XenForo/Model/AddOn.php delete mode 100644 library/DevHelper/XenForo/Route/PrefixAdmin/Templates.php delete mode 100644 library/DevHelper/XenForo/Template/Abstract.php delete mode 100644 library/DevHelper/XenForo/ViewAdmin/AddOn/Upgrade.php delete mode 100644 library/DevHelper/XenForo/ViewRenderer/Json.php delete mode 100644 library/DevHelper/addon-devHelper.xml create mode 100644 xenforo/.gitkeep diff --git a/.gitignore b/.gitignore index abfb9be..e69de29 100755 --- a/.gitignore +++ b/.gitignore @@ -1,13 +0,0 @@ -.DS_Store -*.devhelper -library/DevHelper/DevHelper/Config.php -library/DevHelper/DevHelper/Generated/ -FileSums.php -js/DevHelper/CodeMirror/mode/css/scss_test.js -js/DevHelper/CodeMirror/mode/css/test.js -js/DevHelper/CodeMirror/mode/javascript/test.js -library/DevHelper/DevHelper/XFCP -library/DevHelper/Config.php -.data -docker-compose.override.yml -js/DevHelper/*.min.js diff --git a/addons/.gitkeep b/addons/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/aptana.xml b/aptana.xml deleted file mode 100644 index d94a118..0000000 --- a/aptana.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.css b/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.css deleted file mode 100644 index 677c078..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.css +++ /dev/null @@ -1,32 +0,0 @@ -.CodeMirror-dialog { - position: absolute; - left: 0; right: 0; - background: inherit; - z-index: 15; - padding: .1em .8em; - overflow: hidden; - color: inherit; -} - -.CodeMirror-dialog-top { - border-bottom: 1px solid #eee; - top: 0; -} - -.CodeMirror-dialog-bottom { - border-top: 1px solid #eee; - bottom: 0; -} - -.CodeMirror-dialog input { - border: none; - outline: none; - background: transparent; - width: 20em; - color: inherit; - font-family: monospace; -} - -.CodeMirror-dialog button { - font-size: 70%; -} diff --git a/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.js b/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.js deleted file mode 100644 index f10bb5b..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/dialog/dialog.js +++ /dev/null @@ -1,157 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Open simple dialogs on top of an editor. Relies on dialog.css. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - function dialogDiv(cm, template, bottom) { - var wrap = cm.getWrapperElement(); - var dialog; - dialog = wrap.appendChild(document.createElement("div")); - if (bottom) - dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; - else - dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; - - if (typeof template == "string") { - dialog.innerHTML = template; - } else { // Assuming it's a detached DOM element. - dialog.appendChild(template); - } - return dialog; - } - - function closeNotification(cm, newVal) { - if (cm.state.currentNotificationClose) - cm.state.currentNotificationClose(); - cm.state.currentNotificationClose = newVal; - } - - CodeMirror.defineExtension("openDialog", function(template, callback, options) { - if (!options) options = {}; - - closeNotification(this, null); - - var dialog = dialogDiv(this, template, options.bottom); - var closed = false, me = this; - function close(newVal) { - if (typeof newVal == 'string') { - inp.value = newVal; - } else { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - - if (options.onClose) options.onClose(dialog); - } - } - - var inp = dialog.getElementsByTagName("input")[0], button; - if (inp) { - inp.focus(); - - if (options.value) { - inp.value = options.value; - if (options.selectValueOnOpen !== false) { - inp.select(); - } - } - - if (options.onInput) - CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); - if (options.onKeyUp) - CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); - - CodeMirror.on(inp, "keydown", function(e) { - if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } - if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { - inp.blur(); - CodeMirror.e_stop(e); - close(); - } - if (e.keyCode == 13) callback(inp.value, e); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); - } else if (button = dialog.getElementsByTagName("button")[0]) { - CodeMirror.on(button, "click", function() { - close(); - me.focus(); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); - - button.focus(); - } - return close; - }); - - CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { - closeNotification(this, null); - var dialog = dialogDiv(this, template, options && options.bottom); - var buttons = dialog.getElementsByTagName("button"); - var closed = false, me = this, blurring = 1; - function close() { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - } - buttons[0].focus(); - for (var i = 0; i < buttons.length; ++i) { - var b = buttons[i]; - (function(callback) { - CodeMirror.on(b, "click", function(e) { - CodeMirror.e_preventDefault(e); - close(); - if (callback) callback(me); - }); - })(callbacks[i]); - CodeMirror.on(b, "blur", function() { - --blurring; - setTimeout(function() { if (blurring <= 0) close(); }, 200); - }); - CodeMirror.on(b, "focus", function() { ++blurring; }); - } - }); - - /* - * openNotification - * Opens a notification, that can be closed with an optional timer - * (default 5000ms timer) and always closes on click. - * - * If a notification is opened while another is opened, it will close the - * currently opened one and open the new one immediately. - */ - CodeMirror.defineExtension("openNotification", function(template, options) { - closeNotification(this, close); - var dialog = dialogDiv(this, template, options && options.bottom); - var closed = false, doneTimer; - var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; - - function close() { - if (closed) return; - closed = true; - clearTimeout(doneTimer); - dialog.parentNode.removeChild(dialog); - } - - CodeMirror.on(dialog, 'click', function(e) { - CodeMirror.e_preventDefault(e); - close(); - }); - - if (duration) - doneTimer = setTimeout(close, duration); - - return close; - }); -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/scroll/annotatescrollbar.js b/js/DevHelper/Lib/CodeMirror/addon/scroll/annotatescrollbar.js deleted file mode 100644 index f2276fc..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/scroll/annotatescrollbar.js +++ /dev/null @@ -1,122 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineExtension("annotateScrollbar", function(options) { - if (typeof options == "string") options = {className: options}; - return new Annotation(this, options); - }); - - CodeMirror.defineOption("scrollButtonHeight", 0); - - function Annotation(cm, options) { - this.cm = cm; - this.options = options; - this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight"); - this.annotations = []; - this.doRedraw = this.doUpdate = null; - this.div = cm.getWrapperElement().appendChild(document.createElement("div")); - this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none"; - this.computeScale(); - - function scheduleRedraw(delay) { - clearTimeout(self.doRedraw); - self.doRedraw = setTimeout(function() { self.redraw(); }, delay); - } - - var self = this; - cm.on("refresh", this.resizeHandler = function() { - clearTimeout(self.doUpdate); - self.doUpdate = setTimeout(function() { - if (self.computeScale()) scheduleRedraw(20); - }, 100); - }); - cm.on("markerAdded", this.resizeHandler); - cm.on("markerCleared", this.resizeHandler); - if (options.listenForChanges !== false) - cm.on("change", this.changeHandler = function() { - scheduleRedraw(250); - }); - } - - Annotation.prototype.computeScale = function() { - var cm = this.cm; - var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / - cm.getScrollerElement().scrollHeight - if (hScale != this.hScale) { - this.hScale = hScale; - return true; - } - }; - - Annotation.prototype.update = function(annotations) { - this.annotations = annotations; - this.redraw(); - }; - - Annotation.prototype.redraw = function(compute) { - if (compute !== false) this.computeScale(); - var cm = this.cm, hScale = this.hScale; - - var frag = document.createDocumentFragment(), anns = this.annotations; - - var wrapping = cm.getOption("lineWrapping"); - var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; - var curLine = null, curLineObj = null; - function getY(pos, top) { - if (curLine != pos.line) { - curLine = pos.line; - curLineObj = cm.getLineHandle(curLine); - } - if ((curLineObj.widgets && curLineObj.widgets.length) || - (wrapping && curLineObj.height > singleLineH)) - return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; - var topY = cm.heightAtLine(curLineObj, "local"); - return topY + (top ? 0 : curLineObj.height); - } - - var lastLine = cm.lastLine() - if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { - var ann = anns[i]; - if (ann.to.line > lastLine) continue; - var top = nextTop || getY(ann.from, true) * hScale; - var bottom = getY(ann.to, false) * hScale; - while (i < anns.length - 1) { - if (anns[i + 1].to.line > lastLine) break; - nextTop = getY(anns[i + 1].from, true) * hScale; - if (nextTop > bottom + .9) break; - ann = anns[++i]; - bottom = getY(ann.to, false) * hScale; - } - if (bottom == top) continue; - var height = Math.max(bottom - top, 3); - - var elt = frag.appendChild(document.createElement("div")); - elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " - + (top + this.buttonHeight) + "px; height: " + height + "px"; - elt.className = this.options.className; - if (ann.id) { - elt.setAttribute("annotation-id", ann.id); - } - } - this.div.textContent = ""; - this.div.appendChild(frag); - }; - - Annotation.prototype.clear = function() { - this.cm.off("refresh", this.resizeHandler); - this.cm.off("markerAdded", this.resizeHandler); - this.cm.off("markerCleared", this.resizeHandler); - if (this.changeHandler) this.cm.off("change", this.changeHandler); - this.div.parentNode.removeChild(this.div); - }; -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/scroll/scrollpastend.js b/js/DevHelper/Lib/CodeMirror/addon/scroll/scrollpastend.js deleted file mode 100644 index a2ed089..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/scroll/scrollpastend.js +++ /dev/null @@ -1,48 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.off("change", onChange); - cm.off("refresh", updateBottomMargin); - cm.display.lineSpace.parentNode.style.paddingBottom = ""; - cm.state.scrollPastEndPadding = null; - } - if (val) { - cm.on("change", onChange); - cm.on("refresh", updateBottomMargin); - updateBottomMargin(cm); - } - }); - - function onChange(cm, change) { - if (CodeMirror.changeEnd(change).line == cm.lastLine()) - updateBottomMargin(cm); - } - - function updateBottomMargin(cm) { - var padding = ""; - if (cm.lineCount() > 1) { - var totalH = cm.display.scroller.clientHeight - 30, - lastLineH = cm.getLineHandle(cm.lastLine()).height; - padding = (totalH - lastLineH) + "px"; - } - if (cm.state.scrollPastEndPadding != padding) { - cm.state.scrollPastEndPadding = padding; - cm.display.lineSpace.parentNode.style.paddingBottom = padding; - cm.off("refresh", updateBottomMargin); - cm.setSize(); - cm.on("refresh", updateBottomMargin); - } - } -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.css b/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.css deleted file mode 100644 index 5eea7aa..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.css +++ /dev/null @@ -1,66 +0,0 @@ -.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div { - position: absolute; - background: #ccc; - -moz-box-sizing: border-box; - box-sizing: border-box; - border: 1px solid #bbb; - border-radius: 2px; -} - -.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical { - position: absolute; - z-index: 6; - background: #eee; -} - -.CodeMirror-simplescroll-horizontal { - bottom: 0; left: 0; - height: 8px; -} -.CodeMirror-simplescroll-horizontal div { - bottom: 0; - height: 100%; -} - -.CodeMirror-simplescroll-vertical { - right: 0; top: 0; - width: 8px; -} -.CodeMirror-simplescroll-vertical div { - right: 0; - width: 100%; -} - - -.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler { - display: none; -} - -.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div { - position: absolute; - background: #bcd; - border-radius: 3px; -} - -.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical { - position: absolute; - z-index: 6; -} - -.CodeMirror-overlayscroll-horizontal { - bottom: 0; left: 0; - height: 6px; -} -.CodeMirror-overlayscroll-horizontal div { - bottom: 0; - height: 100%; -} - -.CodeMirror-overlayscroll-vertical { - right: 0; top: 0; - width: 6px; -} -.CodeMirror-overlayscroll-vertical div { - right: 0; - width: 100%; -} diff --git a/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.js b/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.js deleted file mode 100644 index 23f3e03..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/scroll/simplescrollbars.js +++ /dev/null @@ -1,152 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function Bar(cls, orientation, scroll) { - this.orientation = orientation; - this.scroll = scroll; - this.screen = this.total = this.size = 1; - this.pos = 0; - - this.node = document.createElement("div"); - this.node.className = cls + "-" + orientation; - this.inner = this.node.appendChild(document.createElement("div")); - - var self = this; - CodeMirror.on(this.inner, "mousedown", function(e) { - if (e.which != 1) return; - CodeMirror.e_preventDefault(e); - var axis = self.orientation == "horizontal" ? "pageX" : "pageY"; - var start = e[axis], startpos = self.pos; - function done() { - CodeMirror.off(document, "mousemove", move); - CodeMirror.off(document, "mouseup", done); - } - function move(e) { - if (e.which != 1) return done(); - self.moveTo(startpos + (e[axis] - start) * (self.total / self.size)); - } - CodeMirror.on(document, "mousemove", move); - CodeMirror.on(document, "mouseup", done); - }); - - CodeMirror.on(this.node, "click", function(e) { - CodeMirror.e_preventDefault(e); - var innerBox = self.inner.getBoundingClientRect(), where; - if (self.orientation == "horizontal") - where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0; - else - where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0; - self.moveTo(self.pos + where * self.screen); - }); - - function onWheel(e) { - var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"]; - var oldPos = self.pos; - self.moveTo(self.pos + moved); - if (self.pos != oldPos) CodeMirror.e_preventDefault(e); - } - CodeMirror.on(this.node, "mousewheel", onWheel); - CodeMirror.on(this.node, "DOMMouseScroll", onWheel); - } - - Bar.prototype.setPos = function(pos, force) { - if (pos < 0) pos = 0; - if (pos > this.total - this.screen) pos = this.total - this.screen; - if (!force && pos == this.pos) return false; - this.pos = pos; - this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = - (pos * (this.size / this.total)) + "px"; - return true - }; - - Bar.prototype.moveTo = function(pos) { - if (this.setPos(pos)) this.scroll(pos, this.orientation); - } - - var minButtonSize = 10; - - Bar.prototype.update = function(scrollSize, clientSize, barSize) { - var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize - if (sizeChanged) { - this.screen = clientSize; - this.total = scrollSize; - this.size = barSize; - } - - var buttonSize = this.screen * (this.size / this.total); - if (buttonSize < minButtonSize) { - this.size -= minButtonSize - buttonSize; - buttonSize = minButtonSize; - } - this.inner.style[this.orientation == "horizontal" ? "width" : "height"] = - buttonSize + "px"; - this.setPos(this.pos, sizeChanged); - }; - - function SimpleScrollbars(cls, place, scroll) { - this.addClass = cls; - this.horiz = new Bar(cls, "horizontal", scroll); - place(this.horiz.node); - this.vert = new Bar(cls, "vertical", scroll); - place(this.vert.node); - this.width = null; - } - - SimpleScrollbars.prototype.update = function(measure) { - if (this.width == null) { - var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle; - if (style) this.width = parseInt(style.height); - } - var width = this.width || 0; - - var needsH = measure.scrollWidth > measure.clientWidth + 1; - var needsV = measure.scrollHeight > measure.clientHeight + 1; - this.vert.node.style.display = needsV ? "block" : "none"; - this.horiz.node.style.display = needsH ? "block" : "none"; - - if (needsV) { - this.vert.update(measure.scrollHeight, measure.clientHeight, - measure.viewHeight - (needsH ? width : 0)); - this.vert.node.style.bottom = needsH ? width + "px" : "0"; - } - if (needsH) { - this.horiz.update(measure.scrollWidth, measure.clientWidth, - measure.viewWidth - (needsV ? width : 0) - measure.barLeft); - this.horiz.node.style.right = needsV ? width + "px" : "0"; - this.horiz.node.style.left = measure.barLeft + "px"; - } - - return {right: needsV ? width : 0, bottom: needsH ? width : 0}; - }; - - SimpleScrollbars.prototype.setScrollTop = function(pos) { - this.vert.setPos(pos); - }; - - SimpleScrollbars.prototype.setScrollLeft = function(pos) { - this.horiz.setPos(pos); - }; - - SimpleScrollbars.prototype.clear = function() { - var parent = this.horiz.node.parentNode; - parent.removeChild(this.horiz.node); - parent.removeChild(this.vert.node); - }; - - CodeMirror.scrollbarModel.simple = function(place, scroll) { - return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll); - }; - CodeMirror.scrollbarModel.overlay = function(place, scroll) { - return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll); - }; -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/jump-to-line.js b/js/DevHelper/Lib/CodeMirror/addon/search/jump-to-line.js deleted file mode 100644 index 8b599cb..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/jump-to-line.js +++ /dev/null @@ -1,49 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Defines jumpToLine command. Uses dialog.js if present. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../dialog/dialog")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../dialog/dialog"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function dialog(cm, text, shortText, deflt, f) { - if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); - else f(prompt(shortText, deflt)); - } - - var jumpDialog = - 'Jump to line: (Use line:column or scroll% syntax)'; - - function interpretLine(cm, string) { - var num = Number(string) - if (/^[-+]/.test(string)) return cm.getCursor().line + num - else return num - 1 - } - - CodeMirror.commands.jumpToLine = function(cm) { - var cur = cm.getCursor(); - dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) { - if (!posStr) return; - - var match; - if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) { - cm.setCursor(interpretLine(cm, match[1]), Number(match[2])) - } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) { - var line = Math.round(cm.lineCount() * Number(match[1]) / 100); - if (/^[-+]/.test(match[1])) line = cur.line + line + 1; - cm.setCursor(line - 1, cur.ch); - } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) { - cm.setCursor(interpretLine(cm, match[1]), cur.ch); - } - }); - }; - - CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine"; -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/match-highlighter.js b/js/DevHelper/Lib/CodeMirror/addon/search/match-highlighter.js deleted file mode 100644 index 73ba0e0..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/match-highlighter.js +++ /dev/null @@ -1,165 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Highlighting text that matches the selection -// -// Defines an option highlightSelectionMatches, which, when enabled, -// will style strings that match the selection throughout the -// document. -// -// The option can be set to true to simply enable it, or to a -// {minChars, style, wordsOnly, showToken, delay} object to explicitly -// configure it. minChars is the minimum amount of characters that should be -// selected for the behavior to occur, and style is the token style to -// apply to the matches. This will be prefixed by "cm-" to create an -// actual CSS class name. If wordsOnly is enabled, the matches will be -// highlighted only if the selected text is a word. showToken, when enabled, -// will cause the current token to be highlighted when nothing is selected. -// delay is used to specify how much time to wait, in milliseconds, before -// highlighting the matches. If annotateScrollbar is enabled, the occurences -// will be highlighted on the scrollbar via the matchesonscrollbar addon. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./matchesonscrollbar")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./matchesonscrollbar"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var defaults = { - style: "matchhighlight", - minChars: 2, - delay: 100, - wordsOnly: false, - annotateScrollbar: false, - showToken: false, - trim: true - } - - function State(options) { - this.options = {} - for (var name in defaults) - this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name] - this.overlay = this.timeout = null; - this.matchesonscroll = null; - this.active = false; - } - - CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - removeOverlay(cm); - clearTimeout(cm.state.matchHighlighter.timeout); - cm.state.matchHighlighter = null; - cm.off("cursorActivity", cursorActivity); - cm.off("focus", onFocus) - } - if (val) { - var state = cm.state.matchHighlighter = new State(val); - if (cm.hasFocus()) { - state.active = true - highlightMatches(cm) - } else { - cm.on("focus", onFocus) - } - cm.on("cursorActivity", cursorActivity); - } - }); - - function cursorActivity(cm) { - var state = cm.state.matchHighlighter; - if (state.active || cm.hasFocus()) scheduleHighlight(cm, state) - } - - function onFocus(cm) { - var state = cm.state.matchHighlighter - if (!state.active) { - state.active = true - scheduleHighlight(cm, state) - } - } - - function scheduleHighlight(cm, state) { - clearTimeout(state.timeout); - state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay); - } - - function addOverlay(cm, query, hasBoundary, style) { - var state = cm.state.matchHighlighter; - cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); - if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { - var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query; - state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false, - {className: "CodeMirror-selection-highlight-scrollbar"}); - } - } - - function removeOverlay(cm) { - var state = cm.state.matchHighlighter; - if (state.overlay) { - cm.removeOverlay(state.overlay); - state.overlay = null; - if (state.matchesonscroll) { - state.matchesonscroll.clear(); - state.matchesonscroll = null; - } - } - } - - function highlightMatches(cm) { - cm.operation(function() { - var state = cm.state.matchHighlighter; - removeOverlay(cm); - if (!cm.somethingSelected() && state.options.showToken) { - var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken; - var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; - while (start && re.test(line.charAt(start - 1))) --start; - while (end < line.length && re.test(line.charAt(end))) ++end; - if (start < end) - addOverlay(cm, line.slice(start, end), re, state.options.style); - return; - } - var from = cm.getCursor("from"), to = cm.getCursor("to"); - if (from.line != to.line) return; - if (state.options.wordsOnly && !isWord(cm, from, to)) return; - var selection = cm.getRange(from, to) - if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "") - if (selection.length >= state.options.minChars) - addOverlay(cm, selection, false, state.options.style); - }); - } - - function isWord(cm, from, to) { - var str = cm.getRange(from, to); - if (str.match(/^\w+$/) !== null) { - if (from.ch > 0) { - var pos = {line: from.line, ch: from.ch - 1}; - var chr = cm.getRange(pos, from); - if (chr.match(/\W/) === null) return false; - } - if (to.ch < cm.getLine(from.line).length) { - var pos = {line: to.line, ch: to.ch + 1}; - var chr = cm.getRange(to, pos); - if (chr.match(/\W/) === null) return false; - } - return true; - } else return false; - } - - function boundariesAround(stream, re) { - return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && - (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); - } - - function makeOverlay(query, hasBoundary, style) { - return {token: function(stream) { - if (stream.match(query) && - (!hasBoundary || boundariesAround(stream, hasBoundary))) - return style; - stream.next(); - stream.skipTo(query.charAt(0)) || stream.skipToEnd(); - }}; - } -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.css b/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.css deleted file mode 100644 index 77932cc..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.css +++ /dev/null @@ -1,8 +0,0 @@ -.CodeMirror-search-match { - background: gold; - border-top: 1px solid orange; - border-bottom: 1px solid orange; - -moz-box-sizing: border-box; - box-sizing: border-box; - opacity: .5; -} diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.js b/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.js deleted file mode 100644 index 8d19228..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/matchesonscrollbar.js +++ /dev/null @@ -1,97 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { - if (typeof options == "string") options = {className: options}; - if (!options) options = {}; - return new SearchAnnotation(this, query, caseFold, options); - }); - - function SearchAnnotation(cm, query, caseFold, options) { - this.cm = cm; - this.options = options; - var annotateOptions = {listenForChanges: false}; - for (var prop in options) annotateOptions[prop] = options[prop]; - if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; - this.annotation = cm.annotateScrollbar(annotateOptions); - this.query = query; - this.caseFold = caseFold; - this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; - this.matches = []; - this.update = null; - - this.findMatches(); - this.annotation.update(this.matches); - - var self = this; - cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); - } - - var MAX_MATCHES = 1000; - - SearchAnnotation.prototype.findMatches = function() { - if (!this.gap) return; - for (var i = 0; i < this.matches.length; i++) { - var match = this.matches[i]; - if (match.from.line >= this.gap.to) break; - if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); - } - var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); - var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; - while (cursor.findNext()) { - var match = {from: cursor.from(), to: cursor.to()}; - if (match.from.line >= this.gap.to) break; - this.matches.splice(i++, 0, match); - if (this.matches.length > maxMatches) break; - } - this.gap = null; - }; - - function offsetLine(line, changeStart, sizeChange) { - if (line <= changeStart) return line; - return Math.max(changeStart, line + sizeChange); - } - - SearchAnnotation.prototype.onChange = function(change) { - var startLine = change.from.line; - var endLine = CodeMirror.changeEnd(change).line; - var sizeChange = endLine - change.to.line; - if (this.gap) { - this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); - this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); - } else { - this.gap = {from: change.from.line, to: endLine + 1}; - } - - if (sizeChange) for (var i = 0; i < this.matches.length; i++) { - var match = this.matches[i]; - var newFrom = offsetLine(match.from.line, startLine, sizeChange); - if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); - var newTo = offsetLine(match.to.line, startLine, sizeChange); - if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); - } - clearTimeout(this.update); - var self = this; - this.update = setTimeout(function() { self.updateAfterChange(); }, 250); - }; - - SearchAnnotation.prototype.updateAfterChange = function() { - this.findMatches(); - this.annotation.update(this.matches); - }; - - SearchAnnotation.prototype.clear = function() { - this.cm.off("change", this.changeHandler); - this.annotation.clear(); - }; -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/search.js b/js/DevHelper/Lib/CodeMirror/addon/search/search.js deleted file mode 100644 index 236e54c..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/search.js +++ /dev/null @@ -1,252 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Define search commands. Depends on dialog.js or another -// implementation of the openDialog method. - -// Replace works a little oddly -- it will do the replace on the next -// Ctrl-G (or whatever is bound to findNext) press. You prevent a -// replace by making sure the match is no longer selected when hitting -// Ctrl-G. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function searchOverlay(query, caseInsensitive) { - if (typeof query == "string") - query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); - else if (!query.global) - query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); - - return {token: function(stream) { - query.lastIndex = stream.pos; - var match = query.exec(stream.string); - if (match && match.index == stream.pos) { - stream.pos += match[0].length || 1; - return "searching"; - } else if (match) { - stream.pos = match.index; - } else { - stream.skipToEnd(); - } - }}; - } - - function SearchState() { - this.posFrom = this.posTo = this.lastQuery = this.query = null; - this.overlay = null; - } - - function getSearchState(cm) { - return cm.state.search || (cm.state.search = new SearchState()); - } - - function queryCaseInsensitive(query) { - return typeof query == "string" && query == query.toLowerCase(); - } - - function getSearchCursor(cm, query, pos) { - // Heuristic: if the query string is all lowercase, do a case insensitive search. - return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true}); - } - - function persistentDialog(cm, text, deflt, onEnter, onKeyDown) { - cm.openDialog(text, onEnter, { - value: deflt, - selectValueOnOpen: true, - closeOnEnter: false, - onClose: function() { clearSearch(cm); }, - onKeyDown: onKeyDown - }); - } - - function dialog(cm, text, shortText, deflt, f) { - if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); - else f(prompt(shortText, deflt)); - } - - function confirmDialog(cm, text, shortText, fs) { - if (cm.openConfirm) cm.openConfirm(text, fs); - else if (confirm(shortText)) fs[0](); - } - - function parseString(string) { - return string.replace(/\\(.)/g, function(_, ch) { - if (ch == "n") return "\n" - if (ch == "r") return "\r" - return ch - }) - } - - function parseQuery(query) { - var isRE = query.match(/^\/(.*)\/([a-z]*)$/); - if (isRE) { - try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } - catch(e) {} // Not a regular expression after all, do a string search - } else { - query = parseString(query) - } - if (typeof query == "string" ? query == "" : query.test("")) - query = /x^/; - return query; - } - - var queryDialog = - 'Search: (Use /re/ syntax for regexp search)'; - - function startSearch(cm, state, query) { - state.queryText = query; - state.query = parseQuery(query); - cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); - state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); - cm.addOverlay(state.overlay); - if (cm.showMatchesOnScrollbar) { - if (state.annotate) { state.annotate.clear(); state.annotate = null; } - state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); - } - } - - function doSearch(cm, rev, persistent, immediate) { - var state = getSearchState(cm); - if (state.query) return findNext(cm, rev); - var q = cm.getSelection() || state.lastQuery; - if (persistent && cm.openDialog) { - var hiding = null - var searchNext = function(query, event) { - CodeMirror.e_stop(event); - if (!query) return; - if (query != state.queryText) { - startSearch(cm, state, query); - state.posFrom = state.posTo = cm.getCursor(); - } - if (hiding) hiding.style.opacity = 1 - findNext(cm, event.shiftKey, function(_, to) { - var dialog - if (to.line < 3 && document.querySelector && - (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && - dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) - (hiding = dialog).style.opacity = .4 - }) - }; - persistentDialog(cm, queryDialog, q, searchNext, function(event, query) { - var keyName = CodeMirror.keyName(event) - var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName] - if (!cmd) cmd = cm.getOption('extraKeys')[keyName] - if (cmd == "findNext" || cmd == "findPrev" || - cmd == "findPersistentNext" || cmd == "findPersistentPrev") { - CodeMirror.e_stop(event); - startSearch(cm, getSearchState(cm), query); - cm.execCommand(cmd); - } else if (cmd == "find" || cmd == "findPersistent") { - CodeMirror.e_stop(event); - searchNext(query, event); - } - }); - if (immediate && q) { - startSearch(cm, state, q); - findNext(cm, rev); - } - } else { - dialog(cm, queryDialog, "Search for:", q, function(query) { - if (query && !state.query) cm.operation(function() { - startSearch(cm, state, query); - state.posFrom = state.posTo = cm.getCursor(); - findNext(cm, rev); - }); - }); - } - } - - function findNext(cm, rev, callback) {cm.operation(function() { - var state = getSearchState(cm); - var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); - if (!cursor.find(rev)) { - cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); - if (!cursor.find(rev)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20); - state.posFrom = cursor.from(); state.posTo = cursor.to(); - if (callback) callback(cursor.from(), cursor.to()) - });} - - function clearSearch(cm) {cm.operation(function() { - var state = getSearchState(cm); - state.lastQuery = state.query; - if (!state.query) return; - state.query = state.queryText = null; - cm.removeOverlay(state.overlay); - if (state.annotate) { state.annotate.clear(); state.annotate = null; } - });} - - var replaceQueryDialog = - ' (Use /re/ syntax for regexp search)'; - var replacementQueryDialog = 'With: '; - var doReplaceConfirm = 'Replace? '; - - function replaceAll(cm, query, text) { - cm.operation(function() { - for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { - if (typeof query != "string") { - var match = cm.getRange(cursor.from(), cursor.to()).match(query); - cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); - } else cursor.replace(text); - } - }); - } - - function replace(cm, all) { - if (cm.getOption("readOnly")) return; - var query = cm.getSelection() || getSearchState(cm).lastQuery; - var dialogText = '' + (all ? 'Replace all:' : 'Replace:') + ''; - dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) { - if (!query) return; - query = parseQuery(query); - dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { - text = parseString(text) - if (all) { - replaceAll(cm, query, text) - } else { - clearSearch(cm); - var cursor = getSearchCursor(cm, query, cm.getCursor("from")); - var advance = function() { - var start = cursor.from(), match; - if (!(match = cursor.findNext())) { - cursor = getSearchCursor(cm, query); - if (!(match = cursor.findNext()) || - (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); - confirmDialog(cm, doReplaceConfirm, "Replace?", - [function() {doReplace(match);}, advance, - function() {replaceAll(cm, query, text)}]); - }; - var doReplace = function(match) { - cursor.replace(typeof query == "string" ? text : - text.replace(/\$(\d)/g, function(_, i) {return match[i];})); - advance(); - }; - advance(); - } - }); - }); - } - - CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; - CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; - CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);}; - CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);}; - CodeMirror.commands.findNext = doSearch; - CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; - CodeMirror.commands.clearSearch = clearSearch; - CodeMirror.commands.replace = replace; - CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; -}); diff --git a/js/DevHelper/Lib/CodeMirror/addon/search/searchcursor.js b/js/DevHelper/Lib/CodeMirror/addon/search/searchcursor.js deleted file mode 100644 index eccd81a..0000000 --- a/js/DevHelper/Lib/CodeMirror/addon/search/searchcursor.js +++ /dev/null @@ -1,289 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")) - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod) - else // Plain browser env - mod(CodeMirror) -})(function(CodeMirror) { - "use strict" - var Pos = CodeMirror.Pos - - function regexpFlags(regexp) { - var flags = regexp.flags - return flags != null ? flags : (regexp.ignoreCase ? "i" : "") - + (regexp.global ? "g" : "") - + (regexp.multiline ? "m" : "") - } - - function ensureGlobal(regexp) { - return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g") - } - - function maybeMultiline(regexp) { - return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source) - } - - function searchRegexpForward(doc, regexp, start) { - regexp = ensureGlobal(regexp) - for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { - regexp.lastIndex = ch - var string = doc.getLine(line), match = regexp.exec(string) - if (match) - return {from: Pos(line, match.index), - to: Pos(line, match.index + match[0].length), - match: match} - } - } - - function searchRegexpForwardMultiline(doc, regexp, start) { - if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) - - regexp = ensureGlobal(regexp) - var string, chunk = 1 - for (var line = start.line, last = doc.lastLine(); line <= last;) { - // This grows the search buffer in exponentially-sized chunks - // between matches, so that nearby matches are fast and don't - // require concatenating the whole document (in case we're - // searching for something that has tons of matches), but at the - // same time, the amount of retries is limited. - for (var i = 0; i < chunk; i++) { - var curLine = doc.getLine(line++) - string = string == null ? curLine : string + "\n" + curLine - } - chunk = chunk * 2 - regexp.lastIndex = start.ch - var match = regexp.exec(string) - if (match) { - var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") - var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length - return {from: Pos(startLine, startCh), - to: Pos(startLine + inside.length - 1, - inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), - match: match} - } - } - } - - function lastMatchIn(string, regexp) { - var cutOff = 0, match - for (;;) { - regexp.lastIndex = cutOff - var newMatch = regexp.exec(string) - if (!newMatch) return match - match = newMatch - cutOff = match.index + (match[0].length || 1) - if (cutOff == string.length) return match - } - } - - function searchRegexpBackward(doc, regexp, start) { - regexp = ensureGlobal(regexp) - for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { - var string = doc.getLine(line) - if (ch > -1) string = string.slice(0, ch) - var match = lastMatchIn(string, regexp) - if (match) - return {from: Pos(line, match.index), - to: Pos(line, match.index + match[0].length), - match: match} - } - } - - function searchRegexpBackwardMultiline(doc, regexp, start) { - regexp = ensureGlobal(regexp) - var string, chunk = 1 - for (var line = start.line, first = doc.firstLine(); line >= first;) { - for (var i = 0; i < chunk; i++) { - var curLine = doc.getLine(line--) - string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string - } - chunk *= 2 - - var match = lastMatchIn(string, regexp) - if (match) { - var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") - var startLine = line + before.length, startCh = before[before.length - 1].length - return {from: Pos(startLine, startCh), - to: Pos(startLine + inside.length - 1, - inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), - match: match} - } - } - } - - var doFold, noFold - if (String.prototype.normalize) { - doFold = function(str) { return str.normalize("NFD").toLowerCase() } - noFold = function(str) { return str.normalize("NFD") } - } else { - doFold = function(str) { return str.toLowerCase() } - noFold = function(str) { return str } - } - - // Maps a position in a case-folded line back to a position in the original line - // (compensating for codepoints increasing in number during folding) - function adjustPos(orig, folded, pos, foldFunc) { - if (orig.length == folded.length) return pos - for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) { - if (min == max) return min - var mid = (min + max) >> 1 - var len = foldFunc(orig.slice(0, mid)).length - if (len == pos) return mid - else if (len > pos) max = mid - else min = mid + 1 - } - } - - function searchStringForward(doc, query, start, caseFold) { - // Empty string would match anything and never progress, so we - // define it to match nothing instead. - if (!query.length) return null - var fold = caseFold ? doFold : noFold - var lines = fold(query).split(/\r|\n\r?/) - - search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) { - var orig = doc.getLine(line).slice(ch), string = fold(orig) - if (lines.length == 1) { - var found = string.indexOf(lines[0]) - if (found == -1) continue search - var start = adjustPos(orig, string, found, fold) + ch - return {from: Pos(line, adjustPos(orig, string, found, fold) + ch), - to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)} - } else { - var cutFrom = string.length - lines[0].length - if (string.slice(cutFrom) != lines[0]) continue search - for (var i = 1; i < lines.length - 1; i++) - if (fold(doc.getLine(line + i)) != lines[i]) continue search - var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1] - if (end.slice(0, lastLine.length) != lastLine) continue search - return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch), - to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))} - } - } - } - - function searchStringBackward(doc, query, start, caseFold) { - if (!query.length) return null - var fold = caseFold ? doFold : noFold - var lines = fold(query).split(/\r|\n\r?/) - - search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) { - var orig = doc.getLine(line) - if (ch > -1) orig = orig.slice(0, ch) - var string = fold(orig) - if (lines.length == 1) { - var found = string.lastIndexOf(lines[0]) - if (found == -1) continue search - return {from: Pos(line, adjustPos(orig, string, found, fold)), - to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))} - } else { - var lastLine = lines[lines.length - 1] - if (string.slice(0, lastLine.length) != lastLine) continue search - for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++) - if (fold(doc.getLine(start + i)) != lines[i]) continue search - var top = doc.getLine(line + 1 - lines.length), topString = fold(top) - if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search - return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)), - to: Pos(line, adjustPos(orig, string, lastLine.length, fold))} - } - } - } - - function SearchCursor(doc, query, pos, options) { - this.atOccurrence = false - this.doc = doc - pos = pos ? doc.clipPos(pos) : Pos(0, 0) - this.pos = {from: pos, to: pos} - - var caseFold - if (typeof options == "object") { - caseFold = options.caseFold - } else { // Backwards compat for when caseFold was the 4th argument - caseFold = options - options = null - } - - if (typeof query == "string") { - if (caseFold == null) caseFold = false - this.matches = function(reverse, pos) { - return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) - } - } else { - query = ensureGlobal(query) - if (!options || options.multiline !== false) - this.matches = function(reverse, pos) { - return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) - } - else - this.matches = function(reverse, pos) { - return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos) - } - } - } - - SearchCursor.prototype = { - findNext: function() {return this.find(false)}, - findPrevious: function() {return this.find(true)}, - - find: function(reverse) { - var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to)) - - // Implements weird auto-growing behavior on null-matches for - // backwards-compatiblity with the vim code (unfortunately) - while (result && CodeMirror.cmpPos(result.from, result.to) == 0) { - if (reverse) { - if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1) - else if (result.from.line == this.doc.firstLine()) result = null - else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1))) - } else { - if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1) - else if (result.to.line == this.doc.lastLine()) result = null - else result = this.matches(reverse, Pos(result.to.line + 1, 0)) - } - } - - if (result) { - this.pos = result - this.atOccurrence = true - return this.pos.match || true - } else { - var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0) - this.pos = {from: end, to: end} - return this.atOccurrence = false - } - }, - - from: function() {if (this.atOccurrence) return this.pos.from}, - to: function() {if (this.atOccurrence) return this.pos.to}, - - replace: function(newText, origin) { - if (!this.atOccurrence) return - var lines = CodeMirror.splitLines(newText) - this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin) - this.pos.to = Pos(this.pos.from.line + lines.length - 1, - lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)) - } - } - - CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this.doc, query, pos, caseFold) - }) - CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this, query, pos, caseFold) - }) - - CodeMirror.defineExtension("selectMatches", function(query, caseFold) { - var ranges = [] - var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold) - while (cur.findNext()) { - if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break - ranges.push({anchor: cur.from(), head: cur.to()}) - } - if (ranges.length) - this.setSelections(ranges, 0) - }) -}); diff --git a/js/DevHelper/Lib/CodeMirror/lib/codemirror.css b/js/DevHelper/Lib/CodeMirror/lib/codemirror.css deleted file mode 100644 index b008351..0000000 --- a/js/DevHelper/Lib/CodeMirror/lib/codemirror.css +++ /dev/null @@ -1,340 +0,0 @@ -/* BASICS */ - -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; - color: black; -} - -/* PADDING */ - -.CodeMirror-lines { - padding: 4px 0; /* Vertical padding around content */ -} -.CodeMirror pre { - padding: 0 4px; /* Horizontal padding of content */ -} - -.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - background-color: white; /* The little square between H and V scrollbars */ -} - -/* GUTTER */ - -.CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; - white-space: nowrap; -} -.CodeMirror-linenumbers {} -.CodeMirror-linenumber { - padding: 0 3px 0 5px; - min-width: 20px; - text-align: right; - color: #999; - white-space: nowrap; -} - -.CodeMirror-guttermarker { color: black; } -.CodeMirror-guttermarker-subtle { color: #999; } - -/* CURSOR */ - -.CodeMirror-cursor { - border-left: 1px solid black; - border-right: none; - width: 0; -} -/* Shown when moving in bi-directional text */ -.CodeMirror div.CodeMirror-secondarycursor { - border-left: 1px solid silver; -} -.cm-fat-cursor .CodeMirror-cursor { - width: auto; - border: 0 !important; - background: #7e7; -} -.cm-fat-cursor div.CodeMirror-cursors { - z-index: 1; -} - -.cm-animate-fat-cursor { - width: auto; - border: 0; - -webkit-animation: blink 1.06s steps(1) infinite; - -moz-animation: blink 1.06s steps(1) infinite; - animation: blink 1.06s steps(1) infinite; - background-color: #7e7; -} -@-moz-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@-webkit-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} - -/* Can style cursor different in overwrite (non-insert) mode */ -.CodeMirror-overwrite .CodeMirror-cursor {} - -.cm-tab { display: inline-block; text-decoration: inherit; } - -.CodeMirror-rulers { - position: absolute; - left: 0; right: 0; top: -50px; bottom: -20px; - overflow: hidden; -} -.CodeMirror-ruler { - border-left: 1px solid #ccc; - top: 0; bottom: 0; - position: absolute; -} - -/* DEFAULT THEME */ - -.cm-s-default .cm-header {color: blue;} -.cm-s-default .cm-quote {color: #090;} -.cm-negative {color: #d44;} -.cm-positive {color: #292;} -.cm-header, .cm-strong {font-weight: bold;} -.cm-em {font-style: italic;} -.cm-link {text-decoration: underline;} -.cm-strikethrough {text-decoration: line-through;} - -.cm-s-default .cm-keyword {color: #708;} -.cm-s-default .cm-atom {color: #219;} -.cm-s-default .cm-number {color: #164;} -.cm-s-default .cm-def {color: #00f;} -.cm-s-default .cm-variable, -.cm-s-default .cm-punctuation, -.cm-s-default .cm-property, -.cm-s-default .cm-operator {} -.cm-s-default .cm-variable-2 {color: #05a;} -.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;} -.cm-s-default .cm-comment {color: #a50;} -.cm-s-default .cm-string {color: #a11;} -.cm-s-default .cm-string-2 {color: #f50;} -.cm-s-default .cm-meta {color: #555;} -.cm-s-default .cm-qualifier {color: #555;} -.cm-s-default .cm-builtin {color: #30a;} -.cm-s-default .cm-bracket {color: #997;} -.cm-s-default .cm-tag {color: #170;} -.cm-s-default .cm-attribute {color: #00c;} -.cm-s-default .cm-hr {color: #999;} -.cm-s-default .cm-link {color: #00c;} - -.cm-s-default .cm-error {color: #f00;} -.cm-invalidchar {color: #f00;} - -.CodeMirror-composing { border-bottom: 2px solid; } - -/* Default styles for common addons */ - -div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} -.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } -.CodeMirror-activeline-background {background: #e8f2ff;} - -/* STOP */ - -/* The rest of this file contains styles related to the mechanics of - the editor. You probably shouldn't touch them. */ - -.CodeMirror { - position: relative; - overflow: hidden; - background: white; -} - -.CodeMirror-scroll { - overflow: scroll !important; /* Things will break if this is overridden */ - /* 30px is the magic margin used to hide the element's real scrollbars */ - /* See overflow: hidden in .CodeMirror */ - margin-bottom: -30px; margin-right: -30px; - padding-bottom: 30px; - height: 100%; - outline: none; /* Prevent dragging from highlighting the element */ - position: relative; -} -.CodeMirror-sizer { - position: relative; - border-right: 30px solid transparent; -} - -/* The fake, visible scrollbars. Used to force redraw during scrolling - before actual scrolling happens, thus preventing shaking and - flickering artifacts. */ -.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - position: absolute; - z-index: 6; - display: none; -} -.CodeMirror-vscrollbar { - right: 0; top: 0; - overflow-x: hidden; - overflow-y: scroll; -} -.CodeMirror-hscrollbar { - bottom: 0; left: 0; - overflow-y: hidden; - overflow-x: scroll; -} -.CodeMirror-scrollbar-filler { - right: 0; bottom: 0; -} -.CodeMirror-gutter-filler { - left: 0; bottom: 0; -} - -.CodeMirror-gutters { - position: absolute; left: 0; top: 0; - min-height: 100%; - z-index: 3; -} -.CodeMirror-gutter { - white-space: normal; - height: 100%; - display: inline-block; - vertical-align: top; - margin-bottom: -30px; -} -.CodeMirror-gutter-wrapper { - position: absolute; - z-index: 4; - background: none !important; - border: none !important; -} -.CodeMirror-gutter-background { - position: absolute; - top: 0; bottom: 0; - z-index: 4; -} -.CodeMirror-gutter-elt { - position: absolute; - cursor: default; - z-index: 4; -} -.CodeMirror-gutter-wrapper ::selection { background-color: transparent } -.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent } - -.CodeMirror-lines { - cursor: text; - min-height: 1px; /* prevents collapsing before first draw */ -} -.CodeMirror pre { - /* Reset some styles that the rest of the page might have set */ - -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border-width: 0; - background: transparent; - font-family: inherit; - font-size: inherit; - margin: 0; - white-space: pre; - word-wrap: normal; - line-height: inherit; - color: inherit; - z-index: 2; - position: relative; - overflow: visible; - -webkit-tap-highlight-color: transparent; - -webkit-font-variant-ligatures: contextual; - font-variant-ligatures: contextual; -} -.CodeMirror-wrap pre { - word-wrap: break-word; - white-space: pre-wrap; - word-break: normal; -} - -.CodeMirror-linebackground { - position: absolute; - left: 0; right: 0; top: 0; bottom: 0; - z-index: 0; -} - -.CodeMirror-linewidget { - position: relative; - z-index: 2; - overflow: auto; -} - -.CodeMirror-widget {} - -.CodeMirror-rtl pre { direction: rtl; } - -.CodeMirror-code { - outline: none; -} - -/* Force content-box sizing for the elements where we expect it */ -.CodeMirror-scroll, -.CodeMirror-sizer, -.CodeMirror-gutter, -.CodeMirror-gutters, -.CodeMirror-linenumber { - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -.CodeMirror-measure { - position: absolute; - width: 100%; - height: 0; - overflow: hidden; - visibility: hidden; -} - -.CodeMirror-cursor { - position: absolute; - pointer-events: none; -} -.CodeMirror-measure pre { position: static; } - -div.CodeMirror-cursors { - visibility: hidden; - position: relative; - z-index: 3; -} -div.CodeMirror-dragcursors { - visibility: visible; -} - -.CodeMirror-focused div.CodeMirror-cursors { - visibility: visible; -} - -.CodeMirror-selected { background: #d9d9d9; } -.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } -.CodeMirror-crosshair { cursor: crosshair; } -.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } -.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } - -.cm-searching { - background: #ffa; - background: rgba(255, 255, 0, .4); -} - -/* Used to force a border model for a node */ -.cm-force-border { padding-right: .1px; } - -@media print { - /* Hide the cursor when printing */ - .CodeMirror div.CodeMirror-cursors { - visibility: hidden; - } -} - -/* See issue #2901 */ -.cm-tab-wrap-hack:after { content: ''; } - -/* Help users use markselection to safely style text background */ -span.CodeMirror-selectedtext { background: none; } diff --git a/js/DevHelper/Lib/CodeMirror/lib/codemirror.js b/js/DevHelper/Lib/CodeMirror/lib/codemirror.js deleted file mode 100644 index aba145d..0000000 --- a/js/DevHelper/Lib/CodeMirror/lib/codemirror.js +++ /dev/null @@ -1,9479 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.CodeMirror = factory()); -}(this, (function () { 'use strict'; - -// Kludges for bugs and behavior differences that can't be feature -// detected are enabled based on userAgent etc sniffing. -var userAgent = navigator.userAgent -var platform = navigator.platform - -var gecko = /gecko\/\d/i.test(userAgent) -var ie_upto10 = /MSIE \d/.test(userAgent) -var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent) -var edge = /Edge\/(\d+)/.exec(userAgent) -var ie = ie_upto10 || ie_11up || edge -var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]) -var webkit = !edge && /WebKit\//.test(userAgent) -var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent) -var chrome = !edge && /Chrome\//.test(userAgent) -var presto = /Opera\//.test(userAgent) -var safari = /Apple Computer/.test(navigator.vendor) -var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent) -var phantom = /PhantomJS/.test(userAgent) - -var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent) -var android = /Android/.test(userAgent) -// This is woefully incomplete. Suggestions for alternative methods welcome. -var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent) -var mac = ios || /Mac/.test(platform) -var chromeOS = /\bCrOS\b/.test(userAgent) -var windows = /win/i.test(platform) - -var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/) -if (presto_version) { presto_version = Number(presto_version[1]) } -if (presto_version && presto_version >= 15) { presto = false; webkit = true } -// Some browsers use the wrong event properties to signal cmd/ctrl on OS X -var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)) -var captureRightClick = gecko || (ie && ie_version >= 9) - -function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } - -var rmClass = function(node, cls) { - var current = node.className - var match = classTest(cls).exec(current) - if (match) { - var after = current.slice(match.index + match[0].length) - node.className = current.slice(0, match.index) + (after ? match[1] + after : "") - } -} - -function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - { e.removeChild(e.firstChild) } - return e -} - -function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e) -} - -function elt(tag, content, className, style) { - var e = document.createElement(tag) - if (className) { e.className = className } - if (style) { e.style.cssText = style } - if (typeof content == "string") { e.appendChild(document.createTextNode(content)) } - else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } } - return e -} -// wrapper for elt, which removes the elt from the accessibility tree -function eltP(tag, content, className, style) { - var e = elt(tag, content, className, style) - e.setAttribute("role", "presentation") - return e -} - -var range -if (document.createRange) { range = function(node, start, end, endNode) { - var r = document.createRange() - r.setEnd(endNode || node, end) - r.setStart(node, start) - return r -} } -else { range = function(node, start, end) { - var r = document.body.createTextRange() - try { r.moveToElementText(node.parentNode) } - catch(e) { return r } - r.collapse(true) - r.moveEnd("character", end) - r.moveStart("character", start) - return r -} } - -function contains(parent, child) { - if (child.nodeType == 3) // Android browser always returns false when child is a textnode - { child = child.parentNode } - if (parent.contains) - { return parent.contains(child) } - do { - if (child.nodeType == 11) { child = child.host } - if (child == parent) { return true } - } while (child = child.parentNode) -} - -function activeElt() { - // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. - // IE < 10 will throw when accessed while the page is loading or in an iframe. - // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. - var activeElement - try { - activeElement = document.activeElement - } catch(e) { - activeElement = document.body || null - } - while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) - { activeElement = activeElement.shadowRoot.activeElement } - return activeElement -} - -function addClass(node, cls) { - var current = node.className - if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls } -} -function joinClasses(a, b) { - var as = a.split(" ") - for (var i = 0; i < as.length; i++) - { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i] } } - return b -} - -var selectInput = function(node) { node.select() } -if (ios) // Mobile Safari apparently has a bug where select() is broken. - { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } } -else if (ie) // Suppress mysterious IE10 errors - { selectInput = function(node) { try { node.select() } catch(_e) {} } } - -function bind(f) { - var args = Array.prototype.slice.call(arguments, 1) - return function(){return f.apply(null, args)} -} - -function copyObj(obj, target, overwrite) { - if (!target) { target = {} } - for (var prop in obj) - { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - { target[prop] = obj[prop] } } - return target -} - -// Counts the column offset in a string, taking tabs into account. -// Used mostly to find indentation. -function countColumn(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/) - if (end == -1) { end = string.length } - } - for (var i = startIndex || 0, n = startValue || 0;;) { - var nextTab = string.indexOf("\t", i) - if (nextTab < 0 || nextTab >= end) - { return n + (end - i) } - n += nextTab - i - n += tabSize - (n % tabSize) - i = nextTab + 1 - } -} - -var Delayed = function() {this.id = null}; -Delayed.prototype.set = function (ms, f) { - clearTimeout(this.id) - this.id = setTimeout(f, ms) -}; - -function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) - { if (array[i] == elt) { return i } } - return -1 -} - -// Number of pixels added to scroller and sizer to hide scrollbar -var scrollerGap = 30 - -// Returned or thrown by various protocols to signal 'I'm not -// handling this'. -var Pass = {toString: function(){return "CodeMirror.Pass"}} - -// Reused option objects for setSelection & friends -var sel_dontScroll = {scroll: false}; -var sel_mouse = {origin: "*mouse"}; -var sel_move = {origin: "+move"}; -// The inverse of countColumn -- find the offset that corresponds to -// a particular column. -function findColumn(string, goal, tabSize) { - for (var pos = 0, col = 0;;) { - var nextTab = string.indexOf("\t", pos) - if (nextTab == -1) { nextTab = string.length } - var skipped = nextTab - pos - if (nextTab == string.length || col + skipped >= goal) - { return pos + Math.min(skipped, goal - col) } - col += nextTab - pos - col += tabSize - (col % tabSize) - pos = nextTab + 1 - if (col >= goal) { return pos } - } -} - -var spaceStrs = [""] -function spaceStr(n) { - while (spaceStrs.length <= n) - { spaceStrs.push(lst(spaceStrs) + " ") } - return spaceStrs[n] -} - -function lst(arr) { return arr[arr.length-1] } - -function map(array, f) { - var out = [] - for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i) } - return out -} - -function insertSorted(array, value, score) { - var pos = 0, priority = score(value) - while (pos < array.length && score(array[pos]) <= priority) { pos++ } - array.splice(pos, 0, value) -} - -function nothing() {} - -function createObj(base, props) { - var inst - if (Object.create) { - inst = Object.create(base) - } else { - nothing.prototype = base - inst = new nothing() - } - if (props) { copyObj(props, inst) } - return inst -} - -var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/ -function isWordCharBasic(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)) -} -function isWordChar(ch, helper) { - if (!helper) { return isWordCharBasic(ch) } - if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true } - return helper.test(ch) -} - -function isEmpty(obj) { - for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } } - return true -} - -// Extending unicode characters. A series of a non-extending char + -// any number of extending chars is treated as a single unit as far -// as editing and measuring is concerned. This is not fully correct, -// since some scripts/fonts/browsers also treat other configurations -// of code points as a group. -var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/ -function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } - -// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. -function skipExtendingChars(str, pos, dir) { - while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir } - return pos -} - -// Returns the value from the range [`from`; `to`] that satisfies -// `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`. -function findFirst(pred, from, to) { - for (;;) { - if (Math.abs(from - to) <= 1) { return pred(from) ? from : to } - var mid = Math.floor((from + to) / 2) - if (pred(mid)) { to = mid } - else { from = mid } - } -} - -// The display handles the DOM integration, both for input reading -// and content drawing. It holds references to DOM nodes and -// display-related state. - -function Display(place, doc, input) { - var d = this - this.input = input - - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler") - d.scrollbarFiller.setAttribute("cm-not-content", "true") - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler") - d.gutterFiller.setAttribute("cm-not-content", "true") - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = eltP("div", null, "CodeMirror-code") - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1") - d.cursorDiv = elt("div", null, "CodeMirror-cursors") - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure") - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure") - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none") - var lines = eltP("div", [d.lineSpace], "CodeMirror-lines") - // Moved around its parent to cover visible view. - d.mover = elt("div", [lines], null, "position: relative") - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer") - d.sizerWidth = null - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;") - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters") - d.lineGutter = null - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll") - d.scroller.setAttribute("tabIndex", "-1") - // The element in which the editor lives. - d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror") - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 } - if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true } - - if (place) { - if (place.appendChild) { place.appendChild(d.wrapper) } - else { place(d.wrapper) } - } - - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first - d.reportedViewFrom = d.reportedViewTo = doc.first - // Information about the rendered lines. - d.view = [] - d.renderedView = null - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null - // Empty space (in pixels) above the view - d.viewOffset = 0 - d.lastWrapHeight = d.lastWrapWidth = 0 - d.updateLineNumbers = null - - d.nativeBarWidth = d.barHeight = d.barWidth = 0 - d.scrollbarsClipped = false - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null - d.maxLineLength = 0 - d.maxLineChanged = false - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null - - // True when shift is held down. - d.shift = false - - // Used to track whether anything happened since the context menu - // was opened. - d.selForContextMenu = null - - d.activeTouch = null - - input.init(d) -} - -// Find the line object corresponding to the given line number. -function getLine(doc, n) { - n -= doc.first - if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") } - var chunk = doc - while (!chunk.lines) { - for (var i = 0;; ++i) { - var child = chunk.children[i], sz = child.chunkSize() - if (n < sz) { chunk = child; break } - n -= sz - } - } - return chunk.lines[n] -} - -// Get the part of a document between two positions, as an array of -// strings. -function getBetween(doc, start, end) { - var out = [], n = start.line - doc.iter(start.line, end.line + 1, function (line) { - var text = line.text - if (n == end.line) { text = text.slice(0, end.ch) } - if (n == start.line) { text = text.slice(start.ch) } - out.push(text) - ++n - }) - return out -} -// Get the lines between from and to, as array of strings. -function getLines(doc, from, to) { - var out = [] - doc.iter(from, to, function (line) { out.push(line.text) }) // iter aborts when callback returns truthy value - return out -} - -// Update the height of a line, propagating the height change -// upwards to parent nodes. -function updateLineHeight(line, height) { - var diff = height - line.height - if (diff) { for (var n = line; n; n = n.parent) { n.height += diff } } -} - -// Given a line object, find its line number by walking up through -// its parent links. -function lineNo(line) { - if (line.parent == null) { return null } - var cur = line.parent, no = indexOf(cur.lines, line) - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0;; ++i) { - if (chunk.children[i] == cur) { break } - no += chunk.children[i].chunkSize() - } - } - return no + cur.first -} - -// Find the line at the given vertical position, using the height -// information in the document tree. -function lineAtHeight(chunk, h) { - var n = chunk.first - outer: do { - for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) { - var child = chunk.children[i$1], ch = child.height - if (h < ch) { chunk = child; continue outer } - h -= ch - n += child.chunkSize() - } - return n - } while (!chunk.lines) - var i = 0 - for (; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height - if (h < lh) { break } - h -= lh - } - return n + i -} - -function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size} - -function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)) -} - -// A Pos instance represents a position within the text. -function Pos(line, ch, sticky) { - if ( sticky === void 0 ) sticky = null; - - if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) } - this.line = line - this.ch = ch - this.sticky = sticky -} - -// Compare two positions, return 0 if they are the same, a negative -// number when a is less, and a positive number otherwise. -function cmp(a, b) { return a.line - b.line || a.ch - b.ch } - -function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 } - -function copyPos(x) {return Pos(x.line, x.ch)} -function maxPos(a, b) { return cmp(a, b) < 0 ? b : a } -function minPos(a, b) { return cmp(a, b) < 0 ? a : b } - -// Most of the external API clips given positions to make sure they -// actually exist within the document. -function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))} -function clipPos(doc, pos) { - if (pos.line < doc.first) { return Pos(doc.first, 0) } - var last = doc.first + doc.size - 1 - if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) } - return clipToLen(pos, getLine(doc, pos.line).text.length) -} -function clipToLen(pos, linelen) { - var ch = pos.ch - if (ch == null || ch > linelen) { return Pos(pos.line, linelen) } - else if (ch < 0) { return Pos(pos.line, 0) } - else { return pos } -} -function clipPosArray(doc, array) { - var out = [] - for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]) } - return out -} - -// Optimize some code when these features are not used. -var sawReadOnlySpans = false; -var sawCollapsedSpans = false; -function seeReadOnlySpans() { - sawReadOnlySpans = true -} - -function seeCollapsedSpans() { - sawCollapsedSpans = true -} - -// TEXTMARKER SPANS - -function MarkedSpan(marker, from, to) { - this.marker = marker - this.from = from; this.to = to -} - -// Search an array of spans for a span matching the given marker. -function getMarkedSpanFor(spans, marker) { - if (spans) { for (var i = 0; i < spans.length; ++i) { - var span = spans[i] - if (span.marker == marker) { return span } - } } -} -// Remove a span from an array, returning undefined if no spans are -// left (we don't store arrays for lines without spans). -function removeMarkedSpan(spans, span) { - var r - for (var i = 0; i < spans.length; ++i) - { if (spans[i] != span) { (r || (r = [])).push(spans[i]) } } - return r -} -// Add a span to a line. -function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span] - span.marker.attachLine(line) -} - -// Used for the algorithm that adjusts markers for a change in the -// document. These functions cut an array of spans at a given -// character position, returning an array of remaining chunks (or -// undefined if nothing remains). -function markedSpansBefore(old, startCh, isInsert) { - var nw - if (old) { for (var i = 0; i < old.length; ++i) { - var span = old[i], marker = span.marker - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh) - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) - ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)) - } - } } - return nw -} -function markedSpansAfter(old, endCh, isInsert) { - var nw - if (old) { for (var i = 0; i < old.length; ++i) { - var span = old[i], marker = span.marker - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh) - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) - ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)) - } - } } - return nw -} - -// Given a change object, compute the new set of marker spans that -// cover the line in which the change took place. Removes spans -// entirely within the change, reconnects spans belonging to the -// same marker that appear on both sides of the change, and cuts off -// spans partially within the change. Returns an array of span -// arrays with one element for each line in (after) the change. -function stretchSpansOverChange(doc, change) { - if (change.full) { return null } - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans - if (!oldFirst && !oldLast) { return null } - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0 - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert) - var last = markedSpansAfter(oldLast, endCh, isInsert) - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0) - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i] - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker) - if (!found) { span.to = startCh } - else if (sameLine) { span.to = found.to == null ? null : found.to + offset } - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i$1 = 0; i$1 < last.length; ++i$1) { - var span$1 = last[i$1] - if (span$1.to != null) { span$1.to += offset } - if (span$1.from == null) { - var found$1 = getMarkedSpanFor(first, span$1.marker) - if (!found$1) { - span$1.from = offset - if (sameLine) { (first || (first = [])).push(span$1) } - } - } else { - span$1.from += offset - if (sameLine) { (first || (first = [])).push(span$1) } - } - } - } - // Make sure we didn't create any zero-length spans - if (first) { first = clearEmptySpans(first) } - if (last && last != first) { last = clearEmptySpans(last) } - - var newMarkers = [first] - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers - if (gap > 0 && first) - { for (var i$2 = 0; i$2 < first.length; ++i$2) - { if (first[i$2].to == null) - { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)) } } } - for (var i$3 = 0; i$3 < gap; ++i$3) - { newMarkers.push(gapMarkers) } - newMarkers.push(last) - } - return newMarkers -} - -// Remove spans that are empty and don't have a clearWhenEmpty -// option of false. -function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i] - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) - { spans.splice(i--, 1) } - } - if (!spans.length) { return null } - return spans -} - -// Used to 'clip' out readOnly ranges when making a change. -function removeReadOnlyRanges(doc, from, to) { - var markers = null - doc.iter(from.line, to.line + 1, function (line) { - if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - { (markers || (markers = [])).push(mark) } - } } - }) - if (!markers) { return null } - var parts = [{from: from, to: to}] - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0) - for (var j = 0; j < parts.length; ++j) { - var p = parts[j] - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue } - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to) - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) - { newParts.push({from: p.from, to: m.from}) } - if (dto > 0 || !mk.inclusiveRight && !dto) - { newParts.push({from: m.to, to: p.to}) } - parts.splice.apply(parts, newParts) - j += newParts.length - 3 - } - } - return parts -} - -// Connect or disconnect spans from a line. -function detachMarkedSpans(line) { - var spans = line.markedSpans - if (!spans) { return } - for (var i = 0; i < spans.length; ++i) - { spans[i].marker.detachLine(line) } - line.markedSpans = null -} -function attachMarkedSpans(line, spans) { - if (!spans) { return } - for (var i = 0; i < spans.length; ++i) - { spans[i].marker.attachLine(line) } - line.markedSpans = spans -} - -// Helpers used when computing which overlapping collapsed span -// counts as the larger one. -function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 } -function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 } - -// Returns a number indicating which of two overlapping collapsed -// spans is larger (and thus includes the other). Falls back to -// comparing ids when the spans cover exactly the same range. -function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length - if (lenDiff != 0) { return lenDiff } - var aPos = a.find(), bPos = b.find() - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b) - if (fromCmp) { return -fromCmp } - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b) - if (toCmp) { return toCmp } - return b.id - a.id -} - -// Find out whether a line ends or starts in a collapsed span. If -// so, return the marker for that span. -function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found - if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { - sp = sps[i] - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) - { found = sp.marker } - } } - return found -} -function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } -function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } - -// Test whether there exists a collapsed span that partially -// overlaps (covers the start or end, but not both) of a new span. -// Such overlap is not allowed. -function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo) - var sps = sawCollapsedSpans && line.markedSpans - if (sps) { for (var i = 0; i < sps.length; ++i) { - var sp = sps[i] - if (!sp.marker.collapsed) { continue } - var found = sp.marker.find(0) - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker) - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker) - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } - if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || - fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) - { return true } - } } -} - -// A visual line is a line as drawn on the screen. Folding, for -// example, can cause multiple logical lines to appear on the same -// visual line. This finds the start of the visual line that the -// given line is part of (usually that is the line itself). -function visualLine(line) { - var merged - while (merged = collapsedSpanAtStart(line)) - { line = merged.find(-1, true).line } - return line -} - -function visualLineEnd(line) { - var merged - while (merged = collapsedSpanAtEnd(line)) - { line = merged.find(1, true).line } - return line -} - -// Returns an array of logical lines that continue the visual line -// started by the argument, or undefined if there are no such lines. -function visualLineContinued(line) { - var merged, lines - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line - ;(lines || (lines = [])).push(line) - } - return lines -} - -// Get the line number of the start of the visual line that the -// given line number is part of. -function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line) - if (line == vis) { return lineN } - return lineNo(vis) -} - -// Get the line number of the start of the next visual line after -// the given line. -function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) { return lineN } - var line = getLine(doc, lineN), merged - if (!lineIsHidden(doc, line)) { return lineN } - while (merged = collapsedSpanAtEnd(line)) - { line = merged.find(1, true).line } - return lineNo(line) + 1 -} - -// Compute whether a line is hidden. Lines count as hidden when they -// are part of a visual line that starts with another line, or when -// they are entirely covered by collapsed, non-widget span. -function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans - if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { - sp = sps[i] - if (!sp.marker.collapsed) { continue } - if (sp.from == null) { return true } - if (sp.marker.widgetNode) { continue } - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - { return true } - } } -} -function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true) - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) - } - if (span.marker.inclusiveRight && span.to == line.text.length) - { return true } - for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i] - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) { return true } - } -} - -// Find the height above the given line. -function heightAtLine(lineObj) { - lineObj = visualLine(lineObj) - - var h = 0, chunk = lineObj.parent - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i] - if (line == lineObj) { break } - else { h += line.height } - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i$1 = 0; i$1 < p.children.length; ++i$1) { - var cur = p.children[i$1] - if (cur == chunk) { break } - else { h += cur.height } - } - } - return h -} - -// Compute the character length of a line, taking into account -// collapsed ranges (see markText) that might hide parts, and join -// other lines onto it. -function lineLength(line) { - if (line.height == 0) { return 0 } - var len = line.text.length, merged, cur = line - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true) - cur = found.from.line - len += found.from.ch - found.to.ch - } - cur = line - while (merged = collapsedSpanAtEnd(cur)) { - var found$1 = merged.find(0, true) - len -= cur.text.length - found$1.from.ch - cur = found$1.to.line - len += cur.text.length - found$1.to.ch - } - return len -} - -// Find the longest line in the document. -function findMaxLine(cm) { - var d = cm.display, doc = cm.doc - d.maxLine = getLine(doc, doc.first) - d.maxLineLength = lineLength(d.maxLine) - d.maxLineChanged = true - doc.iter(function (line) { - var len = lineLength(line) - if (len > d.maxLineLength) { - d.maxLineLength = len - d.maxLine = line - } - }) -} - -// BIDI HELPERS - -function iterateBidiSections(order, from, to, f) { - if (!order) { return f(from, to, "ltr") } - var found = false - for (var i = 0; i < order.length; ++i) { - var part = order[i] - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr") - found = true - } - } - if (!found) { f(from, to, "ltr") } -} - -var bidiOther = null -function getBidiPartAt(order, ch, sticky) { - var found - bidiOther = null - for (var i = 0; i < order.length; ++i) { - var cur = order[i] - if (cur.from < ch && cur.to > ch) { return i } - if (cur.to == ch) { - if (cur.from != cur.to && sticky == "before") { found = i } - else { bidiOther = i } - } - if (cur.from == ch) { - if (cur.from != cur.to && sticky != "before") { found = i } - else { bidiOther = i } - } - } - return found != null ? found : bidiOther -} - -// Bidirectional ordering algorithm -// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm -// that this (partially) implements. - -// One-char codes used for character types: -// L (L): Left-to-Right -// R (R): Right-to-Left -// r (AL): Right-to-Left Arabic -// 1 (EN): European Number -// + (ES): European Number Separator -// % (ET): European Number Terminator -// n (AN): Arabic Number -// , (CS): Common Number Separator -// m (NSM): Non-Spacing Mark -// b (BN): Boundary Neutral -// s (B): Paragraph Separator -// t (S): Segment Separator -// w (WS): Whitespace -// N (ON): Other Neutrals - -// Returns null if characters are ordered as they appear -// (left-to-right), or an array of sections ({from, to, level} -// objects) in the order in which they occur visually. -var bidiOrdering = (function() { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN" - // Character types for codepoints 0x600 to 0x6f9 - var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111" - function charType(code) { - if (code <= 0xf7) { return lowTypes.charAt(code) } - else if (0x590 <= code && code <= 0x5f4) { return "R" } - else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) } - else if (0x6ee <= code && code <= 0x8ac) { return "r" } - else if (0x2000 <= code && code <= 0x200b) { return "w" } - else if (code == 0x200c) { return "b" } - else { return "L" } - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/ - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/ - - function BidiSpan(level, from, to) { - this.level = level - this.from = from; this.to = to - } - - return function(str, direction) { - var outerType = direction == "ltr" ? "L" : "R" - - if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false } - var len = str.length, types = [] - for (var i = 0; i < len; ++i) - { types.push(charType(str.charCodeAt(i))) } - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) { - var type = types[i$1] - if (type == "m") { types[i$1] = prev } - else { prev = type } - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) { - var type$1 = types[i$2] - if (type$1 == "1" && cur == "r") { types[i$2] = "n" } - else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R" } } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) { - var type$2 = types[i$3] - if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1" } - else if (type$2 == "," && prev$1 == types[i$3+1] && - (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1 } - prev$1 = type$2 - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i$4 = 0; i$4 < len; ++i$4) { - var type$3 = types[i$4] - if (type$3 == ",") { types[i$4] = "N" } - else if (type$3 == "%") { - var end = (void 0) - for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {} - var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N" - for (var j = i$4; j < end; ++j) { types[j] = replace } - i$4 = end - 1 - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) { - var type$4 = types[i$5] - if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L" } - else if (isStrong.test(type$4)) { cur$1 = type$4 } - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i$6 = 0; i$6 < len; ++i$6) { - if (isNeutral.test(types[i$6])) { - var end$1 = (void 0) - for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {} - var before = (i$6 ? types[i$6-1] : outerType) == "L" - var after = (end$1 < len ? types[end$1] : outerType) == "L" - var replace$1 = before == after ? (before ? "L" : "R") : outerType - for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1 } - i$6 = end$1 - 1 - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m - for (var i$7 = 0; i$7 < len;) { - if (countsAsLeft.test(types[i$7])) { - var start = i$7 - for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {} - order.push(new BidiSpan(0, start, i$7)) - } else { - var pos = i$7, at = order.length - for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {} - for (var j$2 = pos; j$2 < i$7;) { - if (countsAsNum.test(types[j$2])) { - if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)) } - var nstart = j$2 - for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {} - order.splice(at, 0, new BidiSpan(2, nstart, j$2)) - pos = j$2 - } else { ++j$2 } - } - if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) } - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length - order.unshift(new BidiSpan(0, 0, m[0].length)) - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length - order.push(new BidiSpan(0, len - m[0].length, len)) - } - - return direction == "rtl" ? order.reverse() : order - } -})() - -// Get the bidi ordering for the given line (and cache it). Returns -// false for lines that are fully left-to-right, and an array of -// BidiSpan objects otherwise. -function getOrder(line, direction) { - var order = line.order - if (order == null) { order = line.order = bidiOrdering(line.text, direction) } - return order -} - -function moveCharLogically(line, ch, dir) { - var target = skipExtendingChars(line.text, ch + dir, dir) - return target < 0 || target > line.text.length ? null : target -} - -function moveLogically(line, start, dir) { - var ch = moveCharLogically(line, start.ch, dir) - return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") -} - -function endOfLine(visually, cm, lineObj, lineNo, dir) { - if (visually) { - var order = getOrder(lineObj, cm.doc.direction) - if (order) { - var part = dir < 0 ? lst(order) : order[0] - var moveInStorageOrder = (dir < 0) == (part.level == 1) - var sticky = moveInStorageOrder ? "after" : "before" - var ch - // With a wrapped rtl chunk (possibly spanning multiple bidi parts), - // it could be that the last bidi part is not on the last visual line, - // since visual lines contain content order-consecutive chunks. - // Thus, in rtl, we are looking for the first (content-order) character - // in the rtl chunk that is on the last line (that is, the same line - // as the last (content-order) character). - if (part.level > 0) { - var prep = prepareMeasureForLine(cm, lineObj) - ch = dir < 0 ? lineObj.text.length - 1 : 0 - var targetTop = measureCharPrepared(cm, prep, ch).top - ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch) - if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1) } - } else { ch = dir < 0 ? part.to : part.from } - return new Pos(lineNo, ch, sticky) - } - } - return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") -} - -function moveVisually(cm, line, start, dir) { - var bidi = getOrder(line, cm.doc.direction) - if (!bidi) { return moveLogically(line, start, dir) } - if (start.ch >= line.text.length) { - start.ch = line.text.length - start.sticky = "before" - } else if (start.ch <= 0) { - start.ch = 0 - start.sticky = "after" - } - var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos] - if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { - // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, - // nothing interesting happens. - return moveLogically(line, start, dir) - } - - var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); } - var prep - var getWrappedLineExtent = function (ch) { - if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } - prep = prep || prepareMeasureForLine(cm, line) - return wrappedLineExtentChar(cm, line, prep, ch) - } - var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch) - - if (cm.doc.direction == "rtl" || part.level == 1) { - var moveInStorageOrder = (part.level == 1) == (dir < 0) - var ch = mv(start, moveInStorageOrder ? 1 : -1) - if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { - // Case 2: We move within an rtl part or in an rtl editor on the same visual line - var sticky = moveInStorageOrder ? "before" : "after" - return new Pos(start.line, ch, sticky) - } - } - - // Case 3: Could not move within this bidi part in this visual line, so leave - // the current bidi part - - var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { - var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder - ? new Pos(start.line, mv(ch, 1), "before") - : new Pos(start.line, ch, "after"); } - - for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { - var part = bidi[partPos] - var moveInStorageOrder = (dir > 0) == (part.level != 1) - var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1) - if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } - ch = moveInStorageOrder ? part.from : mv(part.to, -1) - if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } - } - } - - // Case 3a: Look for other bidi parts on the same visual line - var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent) - if (res) { return res } - - // Case 3b: Look for other bidi parts on the next visual line - var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1) - if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { - res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)) - if (res) { return res } - } - - // Case 4: Nowhere to move - return null -} - -// EVENT HANDLING - -// Lightweight event framework. on/off also work on DOM nodes, -// registering native DOM handlers. - -var noHandlers = [] - -var on = function(emitter, type, f) { - if (emitter.addEventListener) { - emitter.addEventListener(type, f, false) - } else if (emitter.attachEvent) { - emitter.attachEvent("on" + type, f) - } else { - var map = emitter._handlers || (emitter._handlers = {}) - map[type] = (map[type] || noHandlers).concat(f) - } -} - -function getHandlers(emitter, type) { - return emitter._handlers && emitter._handlers[type] || noHandlers -} - -function off(emitter, type, f) { - if (emitter.removeEventListener) { - emitter.removeEventListener(type, f, false) - } else if (emitter.detachEvent) { - emitter.detachEvent("on" + type, f) - } else { - var map = emitter._handlers, arr = map && map[type] - if (arr) { - var index = indexOf(arr, f) - if (index > -1) - { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) } - } - } -} - -function signal(emitter, type /*, values...*/) { - var handlers = getHandlers(emitter, type) - if (!handlers.length) { return } - var args = Array.prototype.slice.call(arguments, 2) - for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args) } -} - -// The DOM events that CodeMirror handles can be overridden by -// registering a (non-DOM) handler on the editor for the event name, -// and preventDefault-ing the event in that handler. -function signalDOMEvent(cm, e, override) { - if (typeof e == "string") - { e = {type: e, preventDefault: function() { this.defaultPrevented = true }} } - signal(cm, override || e.type, cm, e) - return e_defaultPrevented(e) || e.codemirrorIgnore -} - -function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity - if (!arr) { return } - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []) - for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1) - { set.push(arr[i]) } } -} - -function hasHandler(emitter, type) { - return getHandlers(emitter, type).length > 0 -} - -// Add on and off methods to a constructor's prototype, to make -// registering events on such objects more convenient. -function eventMixin(ctor) { - ctor.prototype.on = function(type, f) {on(this, type, f)} - ctor.prototype.off = function(type, f) {off(this, type, f)} -} - -// Due to the fact that we still support jurassic IE versions, some -// compatibility wrappers are needed. - -function e_preventDefault(e) { - if (e.preventDefault) { e.preventDefault() } - else { e.returnValue = false } -} -function e_stopPropagation(e) { - if (e.stopPropagation) { e.stopPropagation() } - else { e.cancelBubble = true } -} -function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false -} -function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)} - -function e_target(e) {return e.target || e.srcElement} -function e_button(e) { - var b = e.which - if (b == null) { - if (e.button & 1) { b = 1 } - else if (e.button & 2) { b = 3 } - else if (e.button & 4) { b = 2 } - } - if (mac && e.ctrlKey && b == 1) { b = 3 } - return b -} - -// Detect drag-and-drop -var dragAndDrop = function() { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie && ie_version < 9) { return false } - var div = elt('div') - return "draggable" in div || "dragDrop" in div -}() - -var zwspSupported -function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b") - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])) - if (measure.firstChild.offsetHeight != 0) - { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) } - } - var node = zwspSupported ? elt("span", "\u200b") : - elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px") - node.setAttribute("cm-text", "") - return node -} - -// Feature-detect IE's crummy client rect reporting for bidi text -var badBidiRects -function hasBadBidiRects(measure) { - if (badBidiRects != null) { return badBidiRects } - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")) - var r0 = range(txt, 0, 1).getBoundingClientRect() - var r1 = range(txt, 1, 2).getBoundingClientRect() - removeChildren(measure) - if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780) - return badBidiRects = (r1.right - r0.right < 3) -} - -// See if "".split is the broken IE version, if so, provide an -// alternative way to split lines. -var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) { - var pos = 0, result = [], l = string.length - while (pos <= l) { - var nl = string.indexOf("\n", pos) - if (nl == -1) { nl = string.length } - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl) - var rt = line.indexOf("\r") - if (rt != -1) { - result.push(line.slice(0, rt)) - pos += rt + 1 - } else { - result.push(line) - pos = nl + 1 - } - } - return result -} : function (string) { return string.split(/\r\n?|\n/); } - -var hasSelection = window.getSelection ? function (te) { - try { return te.selectionStart != te.selectionEnd } - catch(e) { return false } -} : function (te) { - var range - try {range = te.ownerDocument.selection.createRange()} - catch(e) {} - if (!range || range.parentElement() != te) { return false } - return range.compareEndPoints("StartToEnd", range) != 0 -} - -var hasCopyEvent = (function () { - var e = elt("div") - if ("oncopy" in e) { return true } - e.setAttribute("oncopy", "return;") - return typeof e.oncopy == "function" -})() - -var badZoomedRects = null -function hasBadZoomedRects(measure) { - if (badZoomedRects != null) { return badZoomedRects } - var node = removeChildrenAndAdd(measure, elt("span", "x")) - var normal = node.getBoundingClientRect() - var fromRange = range(node, 0, 1).getBoundingClientRect() - return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 -} - -var modes = {}; -var mimeModes = {}; -// Extra arguments are stored as the mode's dependencies, which is -// used by (legacy) mechanisms like loadmode.js to automatically -// load a mode. (Preferred mechanism is the require/define calls.) -function defineMode(name, mode) { - if (arguments.length > 2) - { mode.dependencies = Array.prototype.slice.call(arguments, 2) } - modes[name] = mode -} - -function defineMIME(mime, spec) { - mimeModes[mime] = spec -} - -// Given a MIME type, a {name, ...options} config object, or a name -// string, return a mode config object. -function resolveMode(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec] - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name] - if (typeof found == "string") { found = {name: found} } - spec = createObj(found, spec) - spec.name = found.name - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return resolveMode("application/xml") - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { - return resolveMode("application/json") - } - if (typeof spec == "string") { return {name: spec} } - else { return spec || {name: "null"} } -} - -// Given a mode spec (anything that resolveMode accepts), find and -// initialize an actual mode object. -function getMode(options, spec) { - spec = resolveMode(spec) - var mfactory = modes[spec.name] - if (!mfactory) { return getMode(options, "text/plain") } - var modeObj = mfactory(options, spec) - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name] - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) { continue } - if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop] } - modeObj[prop] = exts[prop] - } - } - modeObj.name = spec.name - if (spec.helperType) { modeObj.helperType = spec.helperType } - if (spec.modeProps) { for (var prop$1 in spec.modeProps) - { modeObj[prop$1] = spec.modeProps[prop$1] } } - - return modeObj -} - -// This can be used to attach properties to mode objects from -// outside the actual mode definition. -var modeExtensions = {} -function extendMode(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}) - copyObj(properties, exts) -} - -function copyState(mode, state) { - if (state === true) { return state } - if (mode.copyState) { return mode.copyState(state) } - var nstate = {} - for (var n in state) { - var val = state[n] - if (val instanceof Array) { val = val.concat([]) } - nstate[n] = val - } - return nstate -} - -// Given a mode and a state (for that mode), find the inner mode and -// state at the position that the state refers to. -function innerMode(mode, state) { - var info - while (mode.innerMode) { - info = mode.innerMode(state) - if (!info || info.mode == mode) { break } - state = info.state - mode = info.mode - } - return info || {mode: mode, state: state} -} - -function startState(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true -} - -// STRING STREAM - -// Fed to the mode parsers, provides helper functions to make -// parsers more succinct. - -var StringStream = function(string, tabSize, lineOracle) { - this.pos = this.start = 0 - this.string = string - this.tabSize = tabSize || 8 - this.lastColumnPos = this.lastColumnValue = 0 - this.lineStart = 0 - this.lineOracle = lineOracle -}; - -StringStream.prototype.eol = function () {return this.pos >= this.string.length}; -StringStream.prototype.sol = function () {return this.pos == this.lineStart}; -StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; -StringStream.prototype.next = function () { - if (this.pos < this.string.length) - { return this.string.charAt(this.pos++) } -}; -StringStream.prototype.eat = function (match) { - var ch = this.string.charAt(this.pos) - var ok - if (typeof match == "string") { ok = ch == match } - else { ok = ch && (match.test ? match.test(ch) : match(ch)) } - if (ok) {++this.pos; return ch} -}; -StringStream.prototype.eatWhile = function (match) { - var start = this.pos - while (this.eat(match)){} - return this.pos > start -}; -StringStream.prototype.eatSpace = function () { - var this$1 = this; - - var start = this.pos - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos } - return this.pos > start -}; -StringStream.prototype.skipToEnd = function () {this.pos = this.string.length}; -StringStream.prototype.skipTo = function (ch) { - var found = this.string.indexOf(ch, this.pos) - if (found > -1) {this.pos = found; return true} -}; -StringStream.prototype.backUp = function (n) {this.pos -= n}; -StringStream.prototype.column = function () { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue) - this.lastColumnPos = this.start - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) -}; -StringStream.prototype.indentation = function () { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) -}; -StringStream.prototype.match = function (pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; } - var substr = this.string.substr(this.pos, pattern.length) - if (cased(substr) == cased(pattern)) { - if (consume !== false) { this.pos += pattern.length } - return true - } - } else { - var match = this.string.slice(this.pos).match(pattern) - if (match && match.index > 0) { return null } - if (match && consume !== false) { this.pos += match[0].length } - return match - } -}; -StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; -StringStream.prototype.hideFirstChars = function (n, inner) { - this.lineStart += n - try { return inner() } - finally { this.lineStart -= n } -}; -StringStream.prototype.lookAhead = function (n) { - var oracle = this.lineOracle - return oracle && oracle.lookAhead(n) -}; - -var SavedContext = function(state, lookAhead) { - this.state = state - this.lookAhead = lookAhead -}; - -var Context = function(doc, state, line, lookAhead) { - this.state = state - this.doc = doc - this.line = line - this.maxLookAhead = lookAhead || 0 -}; - -Context.prototype.lookAhead = function (n) { - var line = this.doc.getLine(this.line + n) - if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n } - return line -}; - -Context.prototype.nextLine = function () { - this.line++ - if (this.maxLookAhead > 0) { this.maxLookAhead-- } -}; - -Context.fromSaved = function (doc, saved, line) { - if (saved instanceof SavedContext) - { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) } - else - { return new Context(doc, copyState(doc.mode, saved), line) } -}; - -Context.prototype.save = function (copy) { - var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state - return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state -}; - - -// Compute a style array (an array starting with a mode generation -// -- for invalidation -- followed by pairs of end positions and -// style strings), which is used to highlight the tokens on the -// line. -function highlightLine(cm, line, context, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {} - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); }, - lineClasses, forceToEnd) - var state = context.state - - // Run overlays, adjust style array. - var loop = function ( o ) { - var overlay = cm.state.overlays[o], i = 1, at = 0 - context.state = true - runMode(cm, line.text, overlay.mode, context, function (end, style) { - var start = i - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i] - if (i_end > end) - { st.splice(i, 1, end, st[i+1], i_end) } - i += 2 - at = Math.min(end, i_end) - } - if (!style) { return } - if (overlay.opaque) { - st.splice(start, i - start, end, "overlay " + style) - i = start + 2 - } else { - for (; start < i; start += 2) { - var cur = st[start+1] - st[start+1] = (cur ? cur + " " : "") + "overlay " + style - } - } - }, lineClasses) - }; - - for (var o = 0; o < cm.state.overlays.length; ++o) loop( o ); - context.state = state - - return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} -} - -function getLineStyles(cm, line, updateFrontier) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var context = getContextBefore(cm, lineNo(line)) - var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state) - var result = highlightLine(cm, line, context) - if (resetState) { context.state = resetState } - line.stateAfter = context.save(!resetState) - line.styles = result.styles - if (result.classes) { line.styleClasses = result.classes } - else if (line.styleClasses) { line.styleClasses = null } - if (updateFrontier === cm.doc.highlightFrontier) - { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) } - } - return line.styles -} - -function getContextBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display - if (!doc.mode.startState) { return new Context(doc, true, n) } - var start = findStartLine(cm, n, precise) - var saved = start > doc.first && getLine(doc, start - 1).stateAfter - var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start) - - doc.iter(start, n, function (line) { - processLine(cm, line.text, context) - var pos = context.line - line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null - context.nextLine() - }) - if (precise) { doc.modeFrontier = context.line } - return context -} - -// Lightweight form of highlight -- proceed over this line and -// update state, but don't save a style array. Used for lines that -// aren't currently visible. -function processLine(cm, text, context, startAt) { - var mode = cm.doc.mode - var stream = new StringStream(text, cm.options.tabSize, context) - stream.start = stream.pos = startAt || 0 - if (text == "") { callBlankLine(mode, context.state) } - while (!stream.eol()) { - readToken(mode, stream, context.state) - stream.start = stream.pos - } -} - -function callBlankLine(mode, state) { - if (mode.blankLine) { return mode.blankLine(state) } - if (!mode.innerMode) { return } - var inner = innerMode(mode, state) - if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) } -} - -function readToken(mode, stream, state, inner) { - for (var i = 0; i < 10; i++) { - if (inner) { inner[0] = innerMode(mode, state).mode } - var style = mode.token(stream, state) - if (stream.pos > stream.start) { return style } - } - throw new Error("Mode " + mode.name + " failed to advance stream.") -} - -var Token = function(stream, type, state) { - this.start = stream.start; this.end = stream.pos - this.string = stream.current() - this.type = type || null - this.state = state -}; - -// Utility for getTokenAt and getLineTokens -function takeToken(cm, pos, precise, asArray) { - var doc = cm.doc, mode = doc.mode, style - pos = clipPos(doc, pos) - var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise) - var stream = new StringStream(line.text, cm.options.tabSize, context), tokens - if (asArray) { tokens = [] } - while ((asArray || stream.pos < pos.ch) && !stream.eol()) { - stream.start = stream.pos - style = readToken(mode, stream, context.state) - if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) } - } - return asArray ? tokens : new Token(stream, style, context.state) -} - -function extractLineClasses(type, output) { - if (type) { for (;;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/) - if (!lineClass) { break } - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length) - var prop = lineClass[1] ? "bgClass" : "textClass" - if (output[prop] == null) - { output[prop] = lineClass[2] } - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) - { output[prop] += " " + lineClass[2] } - } } - return type -} - -// Run the given mode's parser over a line, calling f for each token. -function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans - if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans } - var curStart = 0, curStyle = null - var stream = new StringStream(text, cm.options.tabSize, context), style - var inner = cm.options.addModeClass && [null] - if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses) } - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false - if (forceToEnd) { processLine(cm, text, context, stream.pos) } - stream.pos = text.length - style = null - } else { - style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses) - } - if (inner) { - var mName = inner[0].name - if (mName) { style = "m-" + (style ? mName + " " + style : mName) } - } - if (!flattenSpans || curStyle != style) { - while (curStart < stream.start) { - curStart = Math.min(stream.start, curStart + 5000) - f(curStart, curStyle) - } - curStyle = style - } - stream.start = stream.pos - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 - // characters, and returns inaccurate measurements in nodes - // starting around 5000 chars. - var pos = Math.min(stream.pos, curStart + 5000) - f(pos, curStyle) - curStart = pos - } -} - -// Finds the line to start with when starting a parse. Tries to -// find a line with a stateAfter, so that it can start with a -// valid state. If that fails, it returns the line with the -// smallest indentation, which tends to need the least context to -// parse correctly. -function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100) - for (var search = n; search > lim; --search) { - if (search <= doc.first) { return doc.first } - var line = getLine(doc, search - 1), after = line.stateAfter - if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) - { return search } - var indented = countColumn(line.text, null, cm.options.tabSize) - if (minline == null || minindent > indented) { - minline = search - 1 - minindent = indented - } - } - return minline -} - -function retreatFrontier(doc, n) { - doc.modeFrontier = Math.min(doc.modeFrontier, n) - if (doc.highlightFrontier < n - 10) { return } - var start = doc.first - for (var line = n - 1; line > start; line--) { - var saved = getLine(doc, line).stateAfter - // change is on 3 - // state on line 1 looked ahead 2 -- so saw 3 - // test 1 + 2 < 3 should cover this - if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { - start = line + 1 - break - } - } - doc.highlightFrontier = Math.min(doc.highlightFrontier, start) -} - -// LINE DATA STRUCTURE - -// Line objects. These hold state related to a line, including -// highlighting info (the styles array). -var Line = function(text, markedSpans, estimateHeight) { - this.text = text - attachMarkedSpans(this, markedSpans) - this.height = estimateHeight ? estimateHeight(this) : 1 -}; - -Line.prototype.lineNo = function () { return lineNo(this) }; -eventMixin(Line) - -// Change the content (text, markers) of a line. Automatically -// invalidates cached information and tries to re-estimate the -// line's height. -function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text - if (line.stateAfter) { line.stateAfter = null } - if (line.styles) { line.styles = null } - if (line.order != null) { line.order = null } - detachMarkedSpans(line) - attachMarkedSpans(line, markedSpans) - var estHeight = estimateHeight ? estimateHeight(line) : 1 - if (estHeight != line.height) { updateLineHeight(line, estHeight) } -} - -// Detach a line from the document tree and its markers. -function cleanUpLine(line) { - line.parent = null - detachMarkedSpans(line) -} - -// Convert a style as returned by a mode (either null, or a string -// containing one or more styles) to a CSS style. This is cached, -// and also looks for line-wide styles. -var styleToClassCache = {}; -var styleToClassCacheWithMode = {}; -function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) { return null } - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")) -} - -// Render the DOM representation of the text of a line. Also builds -// up a 'line map', which points at the DOM nodes that represent -// specific stretches of text, and is used by the measuring code. -// The returned object contains the DOM node, this map, and -// information about line-wide styles that were set by the mode. -function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null) - var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, - col: 0, pos: 0, cm: cm, - trailingSpace: false, - splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")} - lineView.measure = {} - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0) - builder.pos = 0 - builder.addToken = buildToken - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) - { builder.addToken = buildTokenBadBidi(builder.addToken, order) } - builder.map = [] - var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line) - insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)) - if (line.styleClasses) { - if (line.styleClasses.bgClass) - { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "") } - if (line.styleClasses.textClass) - { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "") } - } - - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) - { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) } - - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map - lineView.measure.cache = {} - } else { - ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) - ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}) - } - } - - // See issue #2901 - if (webkit) { - var last = builder.content.lastChild - if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) - { builder.content.className = "cm-tab-wrap-hack" } - } - - signal(cm, "renderLine", cm, lineView.line, builder.pre) - if (builder.pre.className) - { builder.textClass = joinClasses(builder.pre.className, builder.textClass || "") } - - return builder -} - -function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar") - token.title = "\\u" + ch.charCodeAt(0).toString(16) - token.setAttribute("aria-label", token.title) - return token -} - -// Build up the DOM representation for a single token, and add it to -// the line map. Takes care to render special characters separately. -function buildToken(builder, text, style, startStyle, endStyle, title, css) { - if (!text) { return } - var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text - var special = builder.cm.state.specialChars, mustWrap = false - var content - if (!special.test(text)) { - builder.col += text.length - content = document.createTextNode(displayText) - builder.map.push(builder.pos, builder.pos + text.length, content) - if (ie && ie_version < 9) { mustWrap = true } - builder.pos += text.length - } else { - content = document.createDocumentFragment() - var pos = 0 - while (true) { - special.lastIndex = pos - var m = special.exec(text) - var skipped = m ? m.index - pos : text.length - pos - if (skipped) { - var txt = document.createTextNode(displayText.slice(pos, pos + skipped)) - if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])) } - else { content.appendChild(txt) } - builder.map.push(builder.pos, builder.pos + skipped, txt) - builder.col += skipped - builder.pos += skipped - } - if (!m) { break } - pos += skipped + 1 - var txt$1 = (void 0) - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize - txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")) - txt$1.setAttribute("role", "presentation") - txt$1.setAttribute("cm-text", "\t") - builder.col += tabWidth - } else if (m[0] == "\r" || m[0] == "\n") { - txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")) - txt$1.setAttribute("cm-text", m[0]) - builder.col += 1 - } else { - txt$1 = builder.cm.options.specialCharPlaceholder(m[0]) - txt$1.setAttribute("cm-text", m[0]) - if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])) } - else { content.appendChild(txt$1) } - builder.col += 1 - } - builder.map.push(builder.pos, builder.pos + 1, txt$1) - builder.pos++ - } - } - builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32 - if (style || startStyle || endStyle || mustWrap || css) { - var fullStyle = style || "" - if (startStyle) { fullStyle += startStyle } - if (endStyle) { fullStyle += endStyle } - var token = elt("span", [content], fullStyle, css) - if (title) { token.title = title } - return builder.content.appendChild(token) - } - builder.content.appendChild(content) -} - -function splitSpaces(text, trailingBefore) { - if (text.length > 1 && !/ /.test(text)) { return text } - var spaceBefore = trailingBefore, result = "" - for (var i = 0; i < text.length; i++) { - var ch = text.charAt(i) - if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) - { ch = "\u00a0" } - result += ch - spaceBefore = ch == " " - } - return result -} - -// Work around nonsense dimensions being reported for stretches of -// right-to-left text. -function buildTokenBadBidi(inner, order) { - return function (builder, text, style, startStyle, endStyle, title, css) { - style = style ? style + " cm-force-border" : "cm-force-border" - var start = builder.pos, end = start + text.length - for (;;) { - // Find the part that overlaps with the start of this text - var part = (void 0) - for (var i = 0; i < order.length; i++) { - part = order[i] - if (part.to > start && part.from <= start) { break } - } - if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) } - inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css) - startStyle = null - text = text.slice(part.to - start) - start = part.to - } - } -} - -function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode - if (widget) { builder.map.push(builder.pos, builder.pos + size, widget) } - if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { - if (!widget) - { widget = builder.content.appendChild(document.createElement("span")) } - widget.setAttribute("cm-marker", marker.id) - } - if (widget) { - builder.cm.display.input.setUneditable(widget) - builder.content.appendChild(widget) - } - builder.pos += size - builder.trailingSpace = false -} - -// Outputs a number of spans to make up a line, taking highlighting -// and marked text into account. -function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0 - if (!spans) { - for (var i$1 = 1; i$1 < styles.length; i$1+=2) - { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)) } - return - } - - var len = allText.length, pos = 0, i = 1, text = "", style, css - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed - for (;;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = css = "" - collapsed = null; nextChange = Infinity - var foundBookmarks = [], endStyles = (void 0) - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { - foundBookmarks.push(m) - } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { - if (sp.to != null && sp.to != pos && nextChange > sp.to) { - nextChange = sp.to - spanEndStyle = "" - } - if (m.className) { spanStyle += " " + m.className } - if (m.css) { css = (css ? css + ";" : "") + m.css } - if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle } - if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to) } - if (m.title && !title) { title = m.title } - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) - { collapsed = sp } - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from - } - } - if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2) - { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1] } } } - - if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2) - { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]) } } - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null) - if (collapsed.to == null) { return } - if (collapsed.to == pos) { collapsed = false } - } - } - if (pos >= len) { break } - - var upto = Math.min(len, nextChange) - while (true) { - if (text) { - var end = pos + text.length - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css) - } - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break} - pos = end - spanStartStyle = "" - } - text = allText.slice(at, at = styles[i++]) - style = interpretTokenStyle(styles[i++], builder.cm.options) - } - } -} - - -// These objects are used to represent the visible (currently drawn) -// part of the document. A LineView may correspond to multiple -// logical lines, if those are connected by collapsed ranges. -function LineView(doc, line, lineN) { - // The starting line - this.line = line - // Continuing lines, if any - this.rest = visualLineContinued(line) - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1 - this.node = this.text = null - this.hidden = lineIsHidden(doc, line) -} - -// Create a range of LineView objects for the given lines. -function buildViewArray(cm, from, to) { - var array = [], nextPos - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos) - nextPos = pos + view.size - array.push(view) - } - return array -} - -var operationGroup = null - -function pushOperation(op) { - if (operationGroup) { - operationGroup.ops.push(op) - } else { - op.ownsGroup = operationGroup = { - ops: [op], - delayedCallbacks: [] - } - } -} - -function fireCallbacksForOps(group) { - // Calls delayed callbacks and cursorActivity handlers until no - // new ones appear - var callbacks = group.delayedCallbacks, i = 0 - do { - for (; i < callbacks.length; i++) - { callbacks[i].call(null) } - for (var j = 0; j < group.ops.length; j++) { - var op = group.ops[j] - if (op.cursorActivityHandlers) - { while (op.cursorActivityCalled < op.cursorActivityHandlers.length) - { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) } } - } - } while (i < callbacks.length) -} - -function finishOperation(op, endCb) { - var group = op.ownsGroup - if (!group) { return } - - try { fireCallbacksForOps(group) } - finally { - operationGroup = null - endCb(group) - } -} - -var orphanDelayedCallbacks = null - -// Often, we want to signal events at a point where we are in the -// middle of some work, but don't want the handler to start calling -// other methods on the editor, which might be in an inconsistent -// state or simply not expect any other events to happen. -// signalLater looks whether there are any handlers, and schedules -// them to be executed when the last operation ends, or, if no -// operation is active, when a timeout fires. -function signalLater(emitter, type /*, values...*/) { - var arr = getHandlers(emitter, type) - if (!arr.length) { return } - var args = Array.prototype.slice.call(arguments, 2), list - if (operationGroup) { - list = operationGroup.delayedCallbacks - } else if (orphanDelayedCallbacks) { - list = orphanDelayedCallbacks - } else { - list = orphanDelayedCallbacks = [] - setTimeout(fireOrphanDelayed, 0) - } - var loop = function ( i ) { - list.push(function () { return arr[i].apply(null, args); }) - }; - - for (var i = 0; i < arr.length; ++i) - loop( i ); -} - -function fireOrphanDelayed() { - var delayed = orphanDelayedCallbacks - orphanDelayedCallbacks = null - for (var i = 0; i < delayed.length; ++i) { delayed[i]() } -} - -// When an aspect of a line changes, a string is added to -// lineView.changes. This updates the relevant part of the line's -// DOM structure. -function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j] - if (type == "text") { updateLineText(cm, lineView) } - else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims) } - else if (type == "class") { updateLineClasses(cm, lineView) } - else if (type == "widget") { updateLineWidgets(cm, lineView, dims) } - } - lineView.changes = null -} - -// Lines with gutter elements, widgets or a background class need to -// be wrapped, and have the extra elements added to the wrapper div -function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative") - if (lineView.text.parentNode) - { lineView.text.parentNode.replaceChild(lineView.node, lineView.text) } - lineView.node.appendChild(lineView.text) - if (ie && ie_version < 8) { lineView.node.style.zIndex = 2 } - } - return lineView.node -} - -function updateLineBackground(cm, lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass - if (cls) { cls += " CodeMirror-linebackground" } - if (lineView.background) { - if (cls) { lineView.background.className = cls } - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null } - } else if (cls) { - var wrap = ensureLineWrapped(lineView) - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild) - cm.display.input.setUneditable(lineView.background) - } -} - -// Wrapper around buildLineContent which will reuse the structure -// in display.externalMeasured when possible. -function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null - lineView.measure = ext.measure - return ext.built - } - return buildLineContent(cm, lineView) -} - -// Redraw the line's text. Interacts with the background and text -// classes because the mode may output tokens that influence these -// classes. -function updateLineText(cm, lineView) { - var cls = lineView.text.className - var built = getLineContent(cm, lineView) - if (lineView.text == lineView.node) { lineView.node = built.pre } - lineView.text.parentNode.replaceChild(built.pre, lineView.text) - lineView.text = built.pre - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass - lineView.textClass = built.textClass - updateLineClasses(cm, lineView) - } else if (cls) { - lineView.text.className = cls - } -} - -function updateLineClasses(cm, lineView) { - updateLineBackground(cm, lineView) - if (lineView.line.wrapClass) - { ensureLineWrapped(lineView).className = lineView.line.wrapClass } - else if (lineView.node != lineView.text) - { lineView.node.className = "" } - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass - lineView.text.className = textClass || "" -} - -function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter) - lineView.gutter = null - } - if (lineView.gutterBackground) { - lineView.node.removeChild(lineView.gutterBackground) - lineView.gutterBackground = null - } - if (lineView.line.gutterClass) { - var wrap = ensureLineWrapped(lineView) - lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, - ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")) - cm.display.input.setUneditable(lineView.gutterBackground) - wrap.insertBefore(lineView.gutterBackground, lineView.text) - } - var markers = lineView.line.gutterMarkers - if (cm.options.lineNumbers || markers) { - var wrap$1 = ensureLineWrapped(lineView) - var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")) - cm.display.input.setUneditable(gutterWrap) - wrap$1.insertBefore(gutterWrap, lineView.text) - if (lineView.line.gutterClass) - { gutterWrap.className += " " + lineView.line.gutterClass } - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - { lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))) } - if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id] - if (found) - { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", - ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))) } - } } - } -} - -function updateLineWidgets(cm, lineView, dims) { - if (lineView.alignable) { lineView.alignable = null } - for (var node = lineView.node.firstChild, next = (void 0); node; node = next) { - next = node.nextSibling - if (node.className == "CodeMirror-linewidget") - { lineView.node.removeChild(node) } - } - insertLineWidgets(cm, lineView, dims) -} - -// Build a line's DOM representation from scratch -function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView) - lineView.text = lineView.node = built.pre - if (built.bgClass) { lineView.bgClass = built.bgClass } - if (built.textClass) { lineView.textClass = built.textClass } - - updateLineClasses(cm, lineView) - updateLineGutter(cm, lineView, lineN, dims) - insertLineWidgets(cm, lineView, dims) - return lineView.node -} - -// A lineView may contain multiple logical lines (when merged by -// collapsed spans). The widgets for all of them need to be drawn. -function insertLineWidgets(cm, lineView, dims) { - insertLineWidgetsFor(cm, lineView.line, lineView, dims, true) - if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) - { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) } } -} - -function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { - if (!line.widgets) { return } - var wrap = ensureLineWrapped(lineView) - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget") - if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true") } - positionLineWidget(widget, node, lineView, dims) - cm.display.input.setUneditable(node) - if (allowAbove && widget.above) - { wrap.insertBefore(node, lineView.gutter || lineView.text) } - else - { wrap.appendChild(node) } - signalLater(widget, "redraw") - } -} - -function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - ;(lineView.alignable || (lineView.alignable = [])).push(node) - var width = dims.wrapperWidth - node.style.left = dims.fixedPos + "px" - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth - node.style.paddingLeft = dims.gutterTotalWidth + "px" - } - node.style.width = width + "px" - } - if (widget.coverGutter) { - node.style.zIndex = 5 - node.style.position = "relative" - if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px" } - } -} - -function widgetHeight(widget) { - if (widget.height != null) { return widget.height } - var cm = widget.doc.cm - if (!cm) { return 0 } - if (!contains(document.body, widget.node)) { - var parentStyle = "position: relative;" - if (widget.coverGutter) - { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;" } - if (widget.noHScroll) - { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;" } - removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)) - } - return widget.height = widget.node.parentNode.offsetHeight -} - -// Return true when the given mouse event happened in a widget -function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || - (n.parentNode == display.sizer && n != display.mover)) - { return true } - } -} - -// POSITION MEASUREMENT - -function paddingTop(display) {return display.lineSpace.offsetTop} -function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight} -function paddingH(display) { - if (display.cachedPaddingH) { return display.cachedPaddingH } - var e = removeChildrenAndAdd(display.measure, elt("pre", "x")) - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle - var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)} - if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data } - return data -} - -function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth } -function displayWidth(cm) { - return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth -} -function displayHeight(cm) { - return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight -} - -// Ensure the lineView.wrapping.heights array is populated. This is -// an array of bottom offsets for the lines that make up a drawn -// line. When lineWrapping is on, there might be more than one -// height. -function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping - var curWidth = wrapping && displayWidth(cm) - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = [] - if (wrapping) { - lineView.measure.width = curWidth - var rects = lineView.text.firstChild.getClientRects() - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1] - if (Math.abs(cur.bottom - next.bottom) > 2) - { heights.push((cur.bottom + next.top) / 2 - rect.top) } - } - } - heights.push(rect.bottom - rect.top) - } -} - -// Find a line map (mapping character offsets to text nodes) and a -// measurement cache for the given line number. (A line view might -// contain multiple lines when collapsed ranges are present.) -function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) - { return {map: lineView.measure.map, cache: lineView.measure.cache} } - for (var i = 0; i < lineView.rest.length; i++) - { if (lineView.rest[i] == line) - { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } } - for (var i$1 = 0; i$1 < lineView.rest.length; i$1++) - { if (lineNo(lineView.rest[i$1]) > lineN) - { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } } -} - -// Render a line into the hidden node display.externalMeasured. Used -// when measurement is needed for a line that's not in the viewport. -function updateExternalMeasurement(cm, line) { - line = visualLine(line) - var lineN = lineNo(line) - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN) - view.lineN = lineN - var built = view.built = buildLineContent(cm, view) - view.text = built.pre - removeChildrenAndAdd(cm.display.lineMeasure, built.pre) - return view -} - -// Get a {top, bottom, left, right} box (in line-local coordinates) -// for a given character. -function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias) -} - -// Find a line view that corresponds to the given line number. -function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) - { return cm.display.view[findViewIndex(cm, lineN)] } - var ext = cm.display.externalMeasured - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) - { return ext } -} - -// Measurement can be split in two steps, the set-up work that -// applies to the whole line, and the measurement of the actual -// character. Functions like coordsChar, that need to do a lot of -// measurements in a row, can thus ensure that the set-up work is -// only done once. -function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line) - var view = findViewForLine(cm, lineN) - if (view && !view.text) { - view = null - } else if (view && view.changes) { - updateLineForChanges(cm, view, lineN, getDimensions(cm)) - cm.curOp.forceUpdate = true - } - if (!view) - { view = updateExternalMeasurement(cm, line) } - - var info = mapFromLineView(view, line, lineN) - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - } -} - -// Given a prepared measurement object, measures the position of an -// actual character (or fetches it from the cache). -function measureCharPrepared(cm, prepared, ch, bias, varHeight) { - if (prepared.before) { ch = -1 } - var key = ch + (bias || ""), found - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key] - } else { - if (!prepared.rect) - { prepared.rect = prepared.view.text.getBoundingClientRect() } - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect) - prepared.hasHeights = true - } - found = measureCharInner(cm, prepared, ch, bias) - if (!found.bogus) { prepared.cache[key] = found } - } - return {left: found.left, right: found.right, - top: varHeight ? found.rtop : found.top, - bottom: varHeight ? found.rbottom : found.bottom} -} - -var nullRect = {left: 0, right: 0, top: 0, bottom: 0} - -function nodeAndOffsetInLineMap(map, ch, bias) { - var node, start, end, collapse, mStart, mEnd - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - mStart = map[i] - mEnd = map[i + 1] - if (ch < mStart) { - start = 0; end = 1 - collapse = "left" - } else if (ch < mEnd) { - start = ch - mStart - end = start + 1 - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart - start = end - 1 - if (ch >= mEnd) { collapse = "right" } - } - if (start != null) { - node = map[i + 2] - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) - { collapse = bias } - if (bias == "left" && start == 0) - { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2] - collapse = "left" - } } - if (bias == "right" && start == mEnd - mStart) - { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2] - collapse = "right" - } } - break - } - } - return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd} -} - -function getUsefulRect(rects, bias) { - var rect = nullRect - if (bias == "left") { for (var i = 0; i < rects.length; i++) { - if ((rect = rects[i]).left != rect.right) { break } - } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) { - if ((rect = rects[i$1]).left != rect.right) { break } - } } - return rect -} - -function measureCharInner(cm, prepared, ch, bias) { - var place = nodeAndOffsetInLineMap(prepared.map, ch, bias) - var node = place.node, start = place.start, end = place.end, collapse = place.collapse - - var rect - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned - while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start } - while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end } - if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) - { rect = node.parentNode.getBoundingClientRect() } - else - { rect = getUsefulRect(range(node, start, end).getClientRects(), bias) } - if (rect.left || rect.right || start == 0) { break } - end = start - start = start - 1 - collapse = "right" - } - if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect) } - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) { collapse = bias = "right" } - var rects - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) - { rect = rects[bias == "right" ? rects.length - 1 : 0] } - else - { rect = node.getBoundingClientRect() } - } - if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0] - if (rSpan) - { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} } - else - { rect = nullRect } - } - - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top - var mid = (rtop + rbot) / 2 - var heights = prepared.view.measure.heights - var i = 0 - for (; i < heights.length - 1; i++) - { if (mid < heights[i]) { break } } - var top = i ? heights[i - 1] : 0, bot = heights[i] - var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot} - if (!rect.left && !rect.right) { result.bogus = true } - if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot } - - return result -} - -// Work around problem with bounding client rects on ranges being -// returned incorrectly when zoomed on IE10 and below. -function maybeUpdateRectForZooming(measure, rect) { - if (!window.screen || screen.logicalXDPI == null || - screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) - { return rect } - var scaleX = screen.logicalXDPI / screen.deviceXDPI - var scaleY = screen.logicalYDPI / screen.deviceYDPI - return {left: rect.left * scaleX, right: rect.right * scaleX, - top: rect.top * scaleY, bottom: rect.bottom * scaleY} -} - -function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {} - lineView.measure.heights = null - if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) - { lineView.measure.caches[i] = {} } } - } -} - -function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null - removeChildren(cm.display.lineMeasure) - for (var i = 0; i < cm.display.view.length; i++) - { clearLineMeasurementCacheFor(cm.display.view[i]) } -} - -function clearCaches(cm) { - clearLineMeasurementCache(cm) - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null - if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true } - cm.display.lineNumChars = null -} - -function pageScrollX() { - // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 - // which causes page_Offset and bounding client rects to use - // different reference viewports and invalidate our calculations. - if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } - return window.pageXOffset || (document.documentElement || document.body).scrollLeft -} -function pageScrollY() { - if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } - return window.pageYOffset || (document.documentElement || document.body).scrollTop -} - -// Converts a {top, bottom, left, right} box from line-local -// coordinates into another coordinate system. Context may be one of -// "line", "div" (display.lineDiv), "local"./null (editor), "window", -// or "page". -function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { - if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]) - rect.top += size; rect.bottom += size - } } } - if (context == "line") { return rect } - if (!context) { context = "local" } - var yOff = heightAtLine(lineObj) - if (context == "local") { yOff += paddingTop(cm.display) } - else { yOff -= cm.display.viewOffset } - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect() - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()) - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()) - rect.left += xOff; rect.right += xOff - } - rect.top += yOff; rect.bottom += yOff - return rect -} - -// Coverts a box from "div" coords to another coordinate system. -// Context may be "window", "page", "div", or "local"./null. -function fromCoordSystem(cm, coords, context) { - if (context == "div") { return coords } - var left = coords.left, top = coords.top - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX() - top -= pageScrollY() - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect() - left += localBox.left - top += localBox.top - } - - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect() - return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top} -} - -function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) { lineObj = getLine(cm.doc, pos.line) } - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) -} - -// Returns a box for a given cursor position, which may have an -// 'other' property containing the position of the secondary cursor -// on a bidi boundary. -// A cursor Pos(line, char, "before") is on the same visual line as `char - 1` -// and after `char - 1` in writing order of `char - 1` -// A cursor Pos(line, char, "after") is on the same visual line as `char` -// and before `char` in writing order of `char` -// Examples (upper-case letters are RTL, lower-case are LTR): -// Pos(0, 1, ...) -// before after -// ab a|b a|b -// aB a|B aB| -// Ab |Ab A|b -// AB B|A B|A -// Every position after the last character on a line is considered to stick -// to the last character on the line. -function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { - lineObj = lineObj || getLine(cm.doc, pos.line) - if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) } - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight) - if (right) { m.left = m.right; } else { m.right = m.left } - return intoCoordSystem(cm, lineObj, m, context) - } - var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky - if (ch >= lineObj.text.length) { - ch = lineObj.text.length - sticky = "before" - } else if (ch <= 0) { - ch = 0 - sticky = "after" - } - if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } - - function getBidi(ch, partPos, invert) { - var part = order[partPos], right = (part.level % 2) != 0 - return get(invert ? ch - 1 : ch, right != invert) - } - var partPos = getBidiPartAt(order, ch, sticky) - var other = bidiOther - var val = getBidi(ch, partPos, sticky == "before") - if (other != null) { val.other = getBidi(ch, other, sticky != "before") } - return val -} - -// Used to cheaply estimate the coordinates for a position. Used for -// intermediate scroll updates. -function estimateCoords(cm, pos) { - var left = 0 - pos = clipPos(cm.doc, pos) - if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch } - var lineObj = getLine(cm.doc, pos.line) - var top = heightAtLine(lineObj) + paddingTop(cm.display) - return {left: left, right: left, top: top, bottom: top + lineObj.height} -} - -// Positions returned by coordsChar contain some extra information. -// xRel is the relative x position of the input coordinates compared -// to the found position (so xRel > 0 means the coordinates are to -// the right of the character position, for example). When outside -// is true, that means the coordinates lie outside the line's -// vertical range. -function PosWithInfo(line, ch, sticky, outside, xRel) { - var pos = Pos(line, ch, sticky) - pos.xRel = xRel - if (outside) { pos.outside = true } - return pos -} - -// Compute the character position closest to the given coordinates. -// Input must be lineSpace-local ("div" coordinate system). -function coordsChar(cm, x, y) { - var doc = cm.doc - y += cm.display.viewOffset - if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) } - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1 - if (lineN > last) - { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) } - if (x < 0) { x = 0 } - - var lineObj = getLine(doc, lineN) - for (;;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y) - var merged = collapsedSpanAtEnd(lineObj) - var mergedPos = merged && merged.find(0, true) - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - { lineN = lineNo(lineObj = mergedPos.to.line) } - else - { return found } - } -} - -function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { - var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); } - var end = lineObj.text.length - var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0) - end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end) - return {begin: begin, end: end} -} - -function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { - var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top - return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) -} - -function coordsCharInner(cm, lineObj, lineNo, x, y) { - y -= heightAtLine(lineObj) - var begin = 0, end = lineObj.text.length - var preparedMeasure = prepareMeasureForLine(cm, lineObj) - var pos - var order = getOrder(lineObj, cm.doc.direction) - if (order) { - if (cm.options.lineWrapping) { - ;var assign; - ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign)) - } - pos = new Pos(lineNo, Math.floor(begin + (end - begin) / 2)) - var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - var dir = beginLeft < x ? 1 : -1 - var prevDiff, diff = beginLeft - x, prevPos - var steps = Math.ceil((end - begin) / 4) - outer: do { - prevDiff = diff - prevPos = pos - var i = 0 - for (; i < steps; ++i) { - var prevPos$1 = pos - pos = moveVisually(cm, lineObj, pos, dir) - if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) { - pos = prevPos$1 - break outer - } - } - diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x - if (steps > 1) { - var diff_change_per_step = Math.abs(diff - prevDiff) / steps - steps = Math.min(steps, Math.ceil(Math.abs(diff) / diff_change_per_step)) - dir = diff < 0 ? 1 : -1 - } - } while (diff != 0 && (steps > 1 || ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff))))) - if (Math.abs(diff) > Math.abs(prevDiff)) { - if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") } - pos = prevPos - } - } else { - var ch = findFirst(function (ch) { - var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line") - if (box.top > y) { - // For the cursor stickiness - end = Math.min(ch, end) - return true - } - else if (box.bottom <= y) { return false } - else if (box.left > x) { return true } - else if (box.right < x) { return false } - else { return (x - box.left < box.right - x) } - }, begin, end) - ch = skipExtendingChars(lineObj.text, ch, 1) - pos = new Pos(lineNo, ch, ch == end ? "before" : "after") - } - var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure) - if (y < coords.top || coords.bottom < y) { pos.outside = true } - pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0) - return pos -} - -var measureText -// Compute the default text height. -function textHeight(display) { - if (display.cachedTextHeight != null) { return display.cachedTextHeight } - if (measureText == null) { - measureText = elt("pre") - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")) - measureText.appendChild(elt("br")) - } - measureText.appendChild(document.createTextNode("x")) - } - removeChildrenAndAdd(display.measure, measureText) - var height = measureText.offsetHeight / 50 - if (height > 3) { display.cachedTextHeight = height } - removeChildren(display.measure) - return height || 1 -} - -// Compute the default character width. -function charWidth(display) { - if (display.cachedCharWidth != null) { return display.cachedCharWidth } - var anchor = elt("span", "xxxxxxxxxx") - var pre = elt("pre", [anchor]) - removeChildrenAndAdd(display.measure, pre) - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10 - if (width > 2) { display.cachedCharWidth = width } - return width || 10 -} - -// Do a bulk-read of the DOM positions and sizes needed to draw the -// view, so that we don't interleave reading and writing to the DOM. -function getDimensions(cm) { - var d = cm.display, left = {}, width = {} - var gutterLeft = d.gutters.clientLeft - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft - width[cm.options.gutters[i]] = n.clientWidth - } - return {fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth} -} - -// Computes display.scroller.scrollLeft + display.gutters.offsetWidth, -// but using getBoundingClientRect to get a sub-pixel-accurate -// result. -function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left -} - -// Returns a function that estimates the height of a line, to use as -// first approximation until the line becomes visible (and is thus -// properly measurable). -function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3) - return function (line) { - if (lineIsHidden(cm.doc, line)) { return 0 } - - var widgetsHeight = 0 - if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height } - } } - - if (wrapping) - { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th } - else - { return widgetsHeight + th } - } -} - -function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm) - doc.iter(function (line) { - var estHeight = est(line) - if (estHeight != line.height) { updateLineHeight(line, estHeight) } - }) -} - -// Given a mouse event, find the corresponding position. If liberal -// is false, it checks whether a gutter or scrollbar was clicked, -// and returns null if it was. forRect is used by rectangular -// selections, and tries to estimate a character position even for -// coordinates beyond the right of the text. -function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display - if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null } - - var x, y, space = display.lineSpace.getBoundingClientRect() - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top } - catch (e) { return null } - var coords = coordsChar(cm, x, y), line - if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)) - } - return coords -} - -// Find the view element corresponding to a given line. Return null -// when the line isn't visible. -function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) { return null } - n -= cm.display.viewFrom - if (n < 0) { return null } - var view = cm.display.view - for (var i = 0; i < view.length; i++) { - n -= view[i].size - if (n < 0) { return i } - } -} - -function updateSelection(cm) { - cm.display.input.showSelection(cm.display.input.prepareSelection()) -} - -function prepareSelection(cm, primary) { - var doc = cm.doc, result = {} - var curFragment = result.cursors = document.createDocumentFragment() - var selFragment = result.selection = document.createDocumentFragment() - - for (var i = 0; i < doc.sel.ranges.length; i++) { - if (primary === false && i == doc.sel.primIndex) { continue } - var range = doc.sel.ranges[i] - if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue } - var collapsed = range.empty() - if (collapsed || cm.options.showCursorWhenSelecting) - { drawSelectionCursor(cm, range.head, curFragment) } - if (!collapsed) - { drawSelectionRange(cm, range, selFragment) } - } - return result -} - -// Draws a cursor for the given range -function drawSelectionCursor(cm, head, output) { - var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine) - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")) - cursor.style.left = pos.left + "px" - cursor.style.top = pos.top + "px" - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px" - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")) - otherCursor.style.display = "" - otherCursor.style.left = pos.other.left + "px" - otherCursor.style.top = pos.other.top + "px" - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px" - } -} - -// Draws the given range as a highlighted selection -function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc - var fragment = document.createDocumentFragment() - var padding = paddingH(cm.display), leftSide = padding.left - var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right - - function add(left, top, width, bottom) { - if (top < 0) { top = 0 } - top = Math.round(top) - bottom = Math.round(bottom) - fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px"))) - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line) - var lineLen = lineObj.text.length - var start, end - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias) - } - - iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right - if (from == to) { - rightPos = leftPos - left = right = leftPos.left - } else { - rightPos = coords(to - 1, "right") - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp } - left = leftPos.left - right = rightPos.right - } - if (fromArg == null && from == 0) { left = leftSide } - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom) - left = leftSide - if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top) } - } - if (toArg == null && to == lineLen) { right = rightSide } - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - { start = leftPos } - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - { end = rightPos } - if (left < leftSide + 1) { left = leftSide } - add(left, rightPos.top, right - left, rightPos.bottom) - }) - return {start: start, end: end} - } - - var sFrom = range.from(), sTo = range.to() - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch) - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line) - var singleVLine = visualLine(fromLine) == visualLine(toLine) - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom) - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom) - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom) - } - } - if (leftEnd.bottom < rightStart.top) - { add(leftSide, leftEnd.bottom, null, rightStart.top) } - } - - output.appendChild(fragment) -} - -// Cursor-blinking -function restartBlink(cm) { - if (!cm.state.focused) { return } - var display = cm.display - clearInterval(display.blinker) - var on = true - display.cursorDiv.style.visibility = "" - if (cm.options.cursorBlinkRate > 0) - { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; }, - cm.options.cursorBlinkRate) } - else if (cm.options.cursorBlinkRate < 0) - { display.cursorDiv.style.visibility = "hidden" } -} - -function ensureFocus(cm) { - if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) } -} - -function delayBlurEvent(cm) { - cm.state.delayingBlurEvent = true - setTimeout(function () { if (cm.state.delayingBlurEvent) { - cm.state.delayingBlurEvent = false - onBlur(cm) - } }, 100) -} - -function onFocus(cm, e) { - if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false } - - if (cm.options.readOnly == "nocursor") { return } - if (!cm.state.focused) { - signal(cm, "focus", cm, e) - cm.state.focused = true - addClass(cm.display.wrapper, "CodeMirror-focused") - // This test prevents this from firing when a context - // menu is closed (since the input reset would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { - cm.display.input.reset() - if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20) } // Issue #1730 - } - cm.display.input.receivedFocus() - } - restartBlink(cm) -} -function onBlur(cm, e) { - if (cm.state.delayingBlurEvent) { return } - - if (cm.state.focused) { - signal(cm, "blur", cm, e) - cm.state.focused = false - rmClass(cm.display.wrapper, "CodeMirror-focused") - } - clearInterval(cm.display.blinker) - setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150) -} - -// Read the actual heights of the rendered lines, and update their -// stored heights to match. -function updateHeightsInViewport(cm) { - var display = cm.display - var prevBottom = display.lineDiv.offsetTop - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], height = (void 0) - if (cur.hidden) { continue } - if (ie && ie_version < 8) { - var bot = cur.node.offsetTop + cur.node.offsetHeight - height = bot - prevBottom - prevBottom = bot - } else { - var box = cur.node.getBoundingClientRect() - height = box.bottom - box.top - } - var diff = cur.line.height - height - if (height < 2) { height = textHeight(display) } - if (diff > .005 || diff < -.005) { - updateLineHeight(cur.line, height) - updateWidgetHeight(cur.line) - if (cur.rest) { for (var j = 0; j < cur.rest.length; j++) - { updateWidgetHeight(cur.rest[j]) } } - } - } -} - -// Read and store the height of line widgets associated with the -// given line. -function updateWidgetHeight(line) { - if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) - { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight } } -} - -// Compute the lines that are visible in a given viewport (defaults -// the the current scroll position). viewport may contain top, -// height, and ensure (see op.scrollToPos) properties. -function visibleLines(display, doc, viewport) { - var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop - top = Math.floor(top - paddingTop(display)) - var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom) - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewport && viewport.ensure) { - var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line - if (ensureFrom < from) { - from = ensureFrom - to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight) - } else if (Math.min(ensureTo, doc.lastLine()) >= to) { - from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight) - to = ensureTo - } - } - return {from: from, to: Math.max(to, from + 1)} -} - -// Re-align line numbers and gutter marks to compensate for -// horizontal scrolling. -function alignHorizontally(cm) { - var display = cm.display, view = display.view - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return } - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft - var gutterW = display.gutters.offsetWidth, left = comp + "px" - for (var i = 0; i < view.length; i++) { if (!view[i].hidden) { - if (cm.options.fixedGutter) { - if (view[i].gutter) - { view[i].gutter.style.left = left } - if (view[i].gutterBackground) - { view[i].gutterBackground.style.left = left } - } - var align = view[i].alignable - if (align) { for (var j = 0; j < align.length; j++) - { align[j].style.left = left } } - } } - if (cm.options.fixedGutter) - { display.gutters.style.left = (comp + gutterW) + "px" } -} - -// Used to ensure that the line number gutter is still the right -// size for the current document size. Returns true when an update -// is needed. -function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) { return false } - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")) - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW - display.lineGutter.style.width = "" - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1 - display.lineNumWidth = display.lineNumInnerWidth + padding - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1 - display.lineGutter.style.width = display.lineNumWidth + "px" - updateGutterSpace(cm) - return true - } - return false -} - -// SCROLLING THINGS INTO VIEW - -// If an editor sits on the top or bottom of the window, partially -// scrolled out of view, this ensures that the cursor is visible. -function maybeScrollWindow(cm, rect) { - if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } - - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null - if (rect.top + box.top < 0) { doScroll = true } - else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false } - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")) - cm.display.lineSpace.appendChild(scrollNode) - scrollNode.scrollIntoView(doScroll) - cm.display.lineSpace.removeChild(scrollNode) - } -} - -// Scroll a given position into view (immediately), verifying that -// it actually became visible (as line heights are accurately -// measured, the position of something may 'drift' during drawing). -function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) { margin = 0 } - var rect - if (!cm.options.lineWrapping && pos == end) { - // Set pos and end to the cursor positions around the character pos sticks to - // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch - // If pos == Pos(_, 0, "before"), pos and end are unchanged - pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos - end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos - } - for (var limit = 0; limit < 5; limit++) { - var changed = false - var coords = cursorCoords(cm, pos) - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end) - rect = {left: Math.min(coords.left, endCoords.left), - top: Math.min(coords.top, endCoords.top) - margin, - right: Math.max(coords.left, endCoords.left), - bottom: Math.max(coords.bottom, endCoords.bottom) + margin} - var scrollPos = calculateScrollPos(cm, rect) - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft - if (scrollPos.scrollTop != null) { - updateScrollTop(cm, scrollPos.scrollTop) - if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true } - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft) - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true } - } - if (!changed) { break } - } - return rect -} - -// Scroll a given set of coordinates into view (immediately). -function scrollIntoView(cm, rect) { - var scrollPos = calculateScrollPos(cm, rect) - if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) } - if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) } -} - -// Calculate a new scroll position needed to scroll the given -// rectangle into view. Returns an object with scrollTop and -// scrollLeft properties. When these are undefined, the -// vertical/horizontal position does not need to be adjusted. -function calculateScrollPos(cm, rect) { - var display = cm.display, snapMargin = textHeight(cm.display) - if (rect.top < 0) { rect.top = 0 } - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop - var screen = displayHeight(cm), result = {} - if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen } - var docBottom = cm.doc.height + paddingVert(display) - var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin - if (rect.top < screentop) { - result.scrollTop = atTop ? 0 : rect.top - } else if (rect.bottom > screentop + screen) { - var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen) - if (newTop != screentop) { result.scrollTop = newTop } - } - - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft - var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0) - var tooWide = rect.right - rect.left > screenw - if (tooWide) { rect.right = rect.left + screenw } - if (rect.left < 10) - { result.scrollLeft = 0 } - else if (rect.left < screenleft) - { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) } - else if (rect.right > screenw + screenleft - 3) - { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw } - return result -} - -// Store a relative adjustment to the scroll position in the current -// operation (to be applied when the operation finishes). -function addToScrollTop(cm, top) { - if (top == null) { return } - resolveScrollToPos(cm) - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top -} - -// Make sure that at the end of the operation the current cursor is -// shown. -function ensureCursorVisible(cm) { - resolveScrollToPos(cm) - var cur = cm.getCursor() - cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin} -} - -function scrollToCoords(cm, x, y) { - if (x != null || y != null) { resolveScrollToPos(cm) } - if (x != null) { cm.curOp.scrollLeft = x } - if (y != null) { cm.curOp.scrollTop = y } -} - -function scrollToRange(cm, range) { - resolveScrollToPos(cm) - cm.curOp.scrollToPos = range -} - -// When an operation has its scrollToPos property set, and another -// scroll action is applied before the end of the operation, this -// 'simulates' scrolling that position into view in a cheap way, so -// that the effect of intermediate scroll commands is not ignored. -function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos - if (range) { - cm.curOp.scrollToPos = null - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to) - scrollToCoordsRange(cm, from, to, range.margin) - } -} - -function scrollToCoordsRange(cm, from, to, margin) { - var sPos = calculateScrollPos(cm, { - left: Math.min(from.left, to.left), - top: Math.min(from.top, to.top) - margin, - right: Math.max(from.right, to.right), - bottom: Math.max(from.bottom, to.bottom) + margin - }) - scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop) -} - -// Sync the scrollable area and scrollbars, ensure the viewport -// covers the visible area. -function updateScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) { return } - if (!gecko) { updateDisplaySimple(cm, {top: val}) } - setScrollTop(cm, val, true) - if (gecko) { updateDisplaySimple(cm) } - startWorker(cm, 100) -} - -function setScrollTop(cm, val, forceScroll) { - val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val) - if (cm.display.scroller.scrollTop == val && !forceScroll) { return } - cm.doc.scrollTop = val - cm.display.scrollbars.setScrollTop(val) - if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val } -} - -// Sync scroller and scrollbar, ensure the gutter elements are -// aligned. -function setScrollLeft(cm, val, isScroller, forceScroll) { - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth) - if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return } - cm.doc.scrollLeft = val - alignHorizontally(cm) - if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val } - cm.display.scrollbars.setScrollLeft(val) -} - -// SCROLLBARS - -// Prepare DOM reads needed to update the scrollbars. Done in one -// shot to minimize update/measure roundtrips. -function measureForScrollbars(cm) { - var d = cm.display, gutterW = d.gutters.offsetWidth - var docH = Math.round(cm.doc.height + paddingVert(cm.display)) - return { - clientHeight: d.scroller.clientHeight, - viewHeight: d.wrapper.clientHeight, - scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, - viewWidth: d.wrapper.clientWidth, - barLeft: cm.options.fixedGutter ? gutterW : 0, - docHeight: docH, - scrollHeight: docH + scrollGap(cm) + d.barHeight, - nativeBarWidth: d.nativeBarWidth, - gutterWidth: gutterW - } -} - -var NativeScrollbars = function(place, scroll, cm) { - this.cm = cm - var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar") - var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar") - place(vert); place(horiz) - - on(vert, "scroll", function () { - if (vert.clientHeight) { scroll(vert.scrollTop, "vertical") } - }) - on(horiz, "scroll", function () { - if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal") } - }) - - this.checkedZeroWidth = false - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px" } -}; - -NativeScrollbars.prototype.update = function (measure) { - var needsH = measure.scrollWidth > measure.clientWidth + 1 - var needsV = measure.scrollHeight > measure.clientHeight + 1 - var sWidth = measure.nativeBarWidth - - if (needsV) { - this.vert.style.display = "block" - this.vert.style.bottom = needsH ? sWidth + "px" : "0" - var totalHeight = measure.viewHeight - (needsH ? sWidth : 0) - // A bug in IE8 can cause this value to be negative, so guard it. - this.vert.firstChild.style.height = - Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px" - } else { - this.vert.style.display = "" - this.vert.firstChild.style.height = "0" - } - - if (needsH) { - this.horiz.style.display = "block" - this.horiz.style.right = needsV ? sWidth + "px" : "0" - this.horiz.style.left = measure.barLeft + "px" - var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0) - this.horiz.firstChild.style.width = - Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px" - } else { - this.horiz.style.display = "" - this.horiz.firstChild.style.width = "0" - } - - if (!this.checkedZeroWidth && measure.clientHeight > 0) { - if (sWidth == 0) { this.zeroWidthHack() } - this.checkedZeroWidth = true - } - - return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0} -}; - -NativeScrollbars.prototype.setScrollLeft = function (pos) { - if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos } - if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") } -}; - -NativeScrollbars.prototype.setScrollTop = function (pos) { - if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos } - if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert") } -}; - -NativeScrollbars.prototype.zeroWidthHack = function () { - var w = mac && !mac_geMountainLion ? "12px" : "18px" - this.horiz.style.height = this.vert.style.width = w - this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none" - this.disableHoriz = new Delayed - this.disableVert = new Delayed -}; - -NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { - bar.style.pointerEvents = "auto" - function maybeDisable() { - // To find out whether the scrollbar is still visible, we - // check whether the element under the pixel in the bottom - // right corner of the scrollbar box is the scrollbar box - // itself (when the bar is still visible) or its filler child - // (when the bar is hidden). If it is still visible, we keep - // it enabled, if it's hidden, we disable pointer events. - var box = bar.getBoundingClientRect() - var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) - : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1) - if (elt != bar) { bar.style.pointerEvents = "none" } - else { delay.set(1000, maybeDisable) } - } - delay.set(1000, maybeDisable) -}; - -NativeScrollbars.prototype.clear = function () { - var parent = this.horiz.parentNode - parent.removeChild(this.horiz) - parent.removeChild(this.vert) -}; - -var NullScrollbars = function () {}; - -NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} }; -NullScrollbars.prototype.setScrollLeft = function () {}; -NullScrollbars.prototype.setScrollTop = function () {}; -NullScrollbars.prototype.clear = function () {}; - -function updateScrollbars(cm, measure) { - if (!measure) { measure = measureForScrollbars(cm) } - var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight - updateScrollbarsInner(cm, measure) - for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { - if (startWidth != cm.display.barWidth && cm.options.lineWrapping) - { updateHeightsInViewport(cm) } - updateScrollbarsInner(cm, measureForScrollbars(cm)) - startWidth = cm.display.barWidth; startHeight = cm.display.barHeight - } -} - -// Re-synchronize the fake scrollbars with the actual size of the -// content. -function updateScrollbarsInner(cm, measure) { - var d = cm.display - var sizes = d.scrollbars.update(measure) - - d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px" - d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px" - d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" - - if (sizes.right && sizes.bottom) { - d.scrollbarFiller.style.display = "block" - d.scrollbarFiller.style.height = sizes.bottom + "px" - d.scrollbarFiller.style.width = sizes.right + "px" - } else { d.scrollbarFiller.style.display = "" } - if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block" - d.gutterFiller.style.height = sizes.bottom + "px" - d.gutterFiller.style.width = measure.gutterWidth + "px" - } else { d.gutterFiller.style.display = "" } -} - -var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars} - -function initScrollbars(cm) { - if (cm.display.scrollbars) { - cm.display.scrollbars.clear() - if (cm.display.scrollbars.addClass) - { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) } - } - - cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) { - cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller) - // Prevent clicks in the scrollbars from killing focus - on(node, "mousedown", function () { - if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0) } - }) - node.setAttribute("cm-not-content", "true") - }, function (pos, axis) { - if (axis == "horizontal") { setScrollLeft(cm, pos) } - else { updateScrollTop(cm, pos) } - }, cm) - if (cm.display.scrollbars.addClass) - { addClass(cm.display.wrapper, cm.display.scrollbars.addClass) } -} - -// Operations are used to wrap a series of changes to the editor -// state in such a way that each change won't have to update the -// cursor and display (which would be awkward, slow, and -// error-prone). Instead, display updates are batched and then all -// combined and executed at once. - -var nextOpId = 0 -// Start a new operation. -function startOperation(cm) { - cm.curOp = { - cm: cm, - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: null, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - focus: false, - id: ++nextOpId // Unique ID - } - pushOperation(cm.curOp) -} - -// Finish an operation, updating the display and signalling delayed events -function endOperation(cm) { - var op = cm.curOp - finishOperation(op, function (group) { - for (var i = 0; i < group.ops.length; i++) - { group.ops[i].cm.curOp = null } - endOperations(group) - }) -} - -// The DOM updates done when an operation finishes are batched so -// that the minimum number of relayouts are required. -function endOperations(group) { - var ops = group.ops - for (var i = 0; i < ops.length; i++) // Read DOM - { endOperation_R1(ops[i]) } - for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe) - { endOperation_W1(ops[i$1]) } - for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM - { endOperation_R2(ops[i$2]) } - for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe) - { endOperation_W2(ops[i$3]) } - for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM - { endOperation_finish(ops[i$4]) } -} - -function endOperation_R1(op) { - var cm = op.cm, display = cm.display - maybeClipScrollbars(cm) - if (op.updateMaxLine) { findMaxLine(cm) } - - op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping - op.update = op.mustUpdate && - new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate) -} - -function endOperation_W1(op) { - op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update) -} - -function endOperation_R2(op) { - var cm = op.cm, display = cm.display - if (op.updatedDisplay) { updateHeightsInViewport(cm) } - - op.barMeasure = measureForScrollbars(cm) - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - // updateDisplay_W2 will use these properties to do the actual resizing - if (display.maxLineChanged && !cm.options.lineWrapping) { - op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3 - cm.display.sizerWidth = op.adjustWidthTo - op.barMeasure.scrollWidth = - Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth) - op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)) - } - - if (op.updatedDisplay || op.selectionChanged) - { op.preparedSelection = display.input.prepareSelection(op.focus) } -} - -function endOperation_W2(op) { - var cm = op.cm - - if (op.adjustWidthTo != null) { - cm.display.sizer.style.minWidth = op.adjustWidthTo + "px" - if (op.maxScrollLeft < cm.doc.scrollLeft) - { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true) } - cm.display.maxLineChanged = false - } - - var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()) - if (op.preparedSelection) - { cm.display.input.showSelection(op.preparedSelection, takeFocus) } - if (op.updatedDisplay || op.startHeight != cm.doc.height) - { updateScrollbars(cm, op.barMeasure) } - if (op.updatedDisplay) - { setDocumentHeight(cm, op.barMeasure) } - - if (op.selectionChanged) { restartBlink(cm) } - - if (cm.state.focused && op.updateInput) - { cm.display.input.reset(op.typing) } - if (takeFocus) { ensureFocus(op.cm) } -} - -function endOperation_finish(op) { - var cm = op.cm, display = cm.display, doc = cm.doc - - if (op.updatedDisplay) { postUpdateDisplay(cm, op.update) } - - // Abort mouse wheel delta measurement, when scrolling explicitly - if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) - { display.wheelStartX = display.wheelStartY = null } - - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll) } - - if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true) } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), - clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin) - maybeScrollWindow(cm, rect) - } - - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers - if (hidden) { for (var i = 0; i < hidden.length; ++i) - { if (!hidden[i].lines.length) { signal(hidden[i], "hide") } } } - if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1) - { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide") } } } - - if (display.wrapper.offsetHeight) - { doc.scrollTop = cm.display.scroller.scrollTop } - - // Fire change events, and delayed event handlers - if (op.changeObjs) - { signal(cm, "changes", cm, op.changeObjs) } - if (op.update) - { op.update.finish() } -} - -// Run the given function in an operation -function runInOp(cm, f) { - if (cm.curOp) { return f() } - startOperation(cm) - try { return f() } - finally { endOperation(cm) } -} -// Wraps a function in an operation. Returns the wrapped function. -function operation(cm, f) { - return function() { - if (cm.curOp) { return f.apply(cm, arguments) } - startOperation(cm) - try { return f.apply(cm, arguments) } - finally { endOperation(cm) } - } -} -// Used to add methods to editor and doc instances, wrapping them in -// operations. -function methodOp(f) { - return function() { - if (this.curOp) { return f.apply(this, arguments) } - startOperation(this) - try { return f.apply(this, arguments) } - finally { endOperation(this) } - } -} -function docMethodOp(f) { - return function() { - var cm = this.cm - if (!cm || cm.curOp) { return f.apply(this, arguments) } - startOperation(cm) - try { return f.apply(this, arguments) } - finally { endOperation(cm) } - } -} - -// Updates the display.view data structure for a given change to the -// document. From and to are in pre-change coordinates. Lendiff is -// the amount of lines added or subtracted by the change. This is -// used for changes that span multiple lines, or change the way -// lines are divided into visual lines. regLineChange (below) -// registers single-line changes. -function regChange(cm, from, to, lendiff) { - if (from == null) { from = cm.doc.first } - if (to == null) { to = cm.doc.first + cm.doc.size } - if (!lendiff) { lendiff = 0 } - - var display = cm.display - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) - { display.updateLineNumbers = from } - - cm.curOp.viewChanged = true - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) - { resetView(cm) } - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm) - } else { - display.viewFrom += lendiff - display.viewTo += lendiff - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm) - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1) - if (cut) { - display.view = display.view.slice(cut.index) - display.viewFrom = cut.lineN - display.viewTo += lendiff - } else { - resetView(cm) - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut$1 = viewCuttingPoint(cm, from, from, -1) - if (cut$1) { - display.view = display.view.slice(0, cut$1.index) - display.viewTo = cut$1.lineN - } else { - resetView(cm) - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1) - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1) - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)) - display.viewTo += lendiff - } else { - resetView(cm) - } - } - - var ext = display.externalMeasured - if (ext) { - if (to < ext.lineN) - { ext.lineN += lendiff } - else if (from < ext.lineN + ext.size) - { display.externalMeasured = null } - } -} - -// Register a change to a single line. Type must be one of "text", -// "gutter", "class", "widget" -function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true - var display = cm.display, ext = cm.display.externalMeasured - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) - { display.externalMeasured = null } - - if (line < display.viewFrom || line >= display.viewTo) { return } - var lineView = display.view[findViewIndex(cm, line)] - if (lineView.node == null) { return } - var arr = lineView.changes || (lineView.changes = []) - if (indexOf(arr, type) == -1) { arr.push(type) } -} - -// Clear the view. -function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first - cm.display.view = [] - cm.display.viewOffset = 0 -} - -function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view - if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) - { return {index: index, lineN: newN} } - var n = cm.display.viewFrom - for (var i = 0; i < index; i++) - { n += view[i].size } - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) { return null } - diff = (n + view[index].size) - oldN - index++ - } else { - diff = n - oldN - } - oldN += diff; newN += diff - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) { return null } - newN += dir * view[index - (dir < 0 ? 1 : 0)].size - index += dir - } - return {index: index, lineN: newN} -} - -// Force the view to cover a given range, adding empty view element -// or clipping off existing ones as needed. -function adjustView(cm, from, to) { - var display = cm.display, view = display.view - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to) - display.viewFrom = from - } else { - if (display.viewFrom > from) - { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view) } - else if (display.viewFrom < from) - { display.view = display.view.slice(findViewIndex(cm, from)) } - display.viewFrom = from - if (display.viewTo < to) - { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)) } - else if (display.viewTo > to) - { display.view = display.view.slice(0, findViewIndex(cm, to)) } - } - display.viewTo = to -} - -// Count the number of lines in the view whose DOM representation is -// out of date (or nonexistent). -function countDirtyView(cm) { - var view = cm.display.view, dirty = 0 - for (var i = 0; i < view.length; i++) { - var lineView = view[i] - if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty } - } - return dirty -} - -// HIGHLIGHT WORKER - -function startWorker(cm, time) { - if (cm.doc.highlightFrontier < cm.display.viewTo) - { cm.state.highlight.set(time, bind(highlightWorker, cm)) } -} - -function highlightWorker(cm) { - var doc = cm.doc - if (doc.highlightFrontier >= cm.display.viewTo) { return } - var end = +new Date + cm.options.workTime - var context = getContextBefore(cm, doc.highlightFrontier) - var changedLines = [] - - doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { - if (context.line >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles - var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null - var highlighted = highlightLine(cm, line, context, true) - if (resetState) { context.state = resetState } - line.styles = highlighted.styles - var oldCls = line.styleClasses, newCls = highlighted.classes - if (newCls) { line.styleClasses = newCls } - else if (oldCls) { line.styleClasses = null } - var ischange = !oldStyles || oldStyles.length != line.styles.length || - oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass) - for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i] } - if (ischange) { changedLines.push(context.line) } - line.stateAfter = context.save() - context.nextLine() - } else { - if (line.text.length <= cm.options.maxHighlightLength) - { processLine(cm, line.text, context) } - line.stateAfter = context.line % 5 == 0 ? context.save() : null - context.nextLine() - } - if (+new Date > end) { - startWorker(cm, cm.options.workDelay) - return true - } - }) - doc.highlightFrontier = context.line - doc.modeFrontier = Math.max(doc.modeFrontier, context.line) - if (changedLines.length) { runInOp(cm, function () { - for (var i = 0; i < changedLines.length; i++) - { regLineChange(cm, changedLines[i], "text") } - }) } -} - -// DISPLAY DRAWING - -var DisplayUpdate = function(cm, viewport, force) { - var display = cm.display - - this.viewport = viewport - // Store some values that we'll need later (but don't want to force a relayout for) - this.visible = visibleLines(display, cm.doc, viewport) - this.editorIsHidden = !display.wrapper.offsetWidth - this.wrapperHeight = display.wrapper.clientHeight - this.wrapperWidth = display.wrapper.clientWidth - this.oldDisplayWidth = displayWidth(cm) - this.force = force - this.dims = getDimensions(cm) - this.events = [] -}; - -DisplayUpdate.prototype.signal = function (emitter, type) { - if (hasHandler(emitter, type)) - { this.events.push(arguments) } -}; -DisplayUpdate.prototype.finish = function () { - var this$1 = this; - - for (var i = 0; i < this.events.length; i++) - { signal.apply(null, this$1.events[i]) } -}; - -function maybeClipScrollbars(cm) { - var display = cm.display - if (!display.scrollbarsClipped && display.scroller.offsetWidth) { - display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth - display.heightForcer.style.height = scrollGap(cm) + "px" - display.sizer.style.marginBottom = -display.nativeBarWidth + "px" - display.sizer.style.borderRightWidth = scrollGap(cm) + "px" - display.scrollbarsClipped = true - } -} - -function selectionSnapshot(cm) { - if (cm.hasFocus()) { return null } - var active = activeElt() - if (!active || !contains(cm.display.lineDiv, active)) { return null } - var result = {activeElt: active} - if (window.getSelection) { - var sel = window.getSelection() - if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { - result.anchorNode = sel.anchorNode - result.anchorOffset = sel.anchorOffset - result.focusNode = sel.focusNode - result.focusOffset = sel.focusOffset - } - } - return result -} - -function restoreSelection(snapshot) { - if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return } - snapshot.activeElt.focus() - if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { - var sel = window.getSelection(), range = document.createRange() - range.setEnd(snapshot.anchorNode, snapshot.anchorOffset) - range.collapse(false) - sel.removeAllRanges() - sel.addRange(range) - sel.extend(snapshot.focusNode, snapshot.focusOffset) - } -} - -// Does the actual updating of the line display. Bails out -// (returning false) when there is nothing to be done and forced is -// false. -function updateDisplayIfNeeded(cm, update) { - var display = cm.display, doc = cm.doc - - if (update.editorIsHidden) { - resetView(cm) - return false - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!update.force && - update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && - display.renderedView == display.view && countDirtyView(cm) == 0) - { return false } - - if (maybeUpdateLineNumberWidth(cm)) { - resetView(cm) - update.dims = getDimensions(cm) - } - - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size - var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first) - var to = Math.min(end, update.visible.to + cm.options.viewportMargin) - if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom) } - if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo) } - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from) - to = visualLineEndNo(cm.doc, to) - } - - var different = from != display.viewFrom || to != display.viewTo || - display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth - adjustView(cm, from, to) - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)) - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px" - - var toUpdate = countDirtyView(cm) - if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) - { return false } - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var selSnapshot = selectionSnapshot(cm) - if (toUpdate > 4) { display.lineDiv.style.display = "none" } - patchDisplay(cm, display.updateLineNumbers, update.dims) - if (toUpdate > 4) { display.lineDiv.style.display = "" } - display.renderedView = display.view - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - restoreSelection(selSnapshot) - - // Prevent selection and cursors from interfering with the scroll - // width and height. - removeChildren(display.cursorDiv) - removeChildren(display.selectionDiv) - display.gutters.style.height = display.sizer.style.minHeight = 0 - - if (different) { - display.lastWrapHeight = update.wrapperHeight - display.lastWrapWidth = update.wrapperWidth - startWorker(cm, 400) - } - - display.updateLineNumbers = null - - return true -} - -function postUpdateDisplay(cm, update) { - var viewport = update.viewport - - for (var first = true;; first = false) { - if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { - // Clip forced viewport to actual scrollable area. - if (viewport && viewport.top != null) - { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)} } - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - update.visible = visibleLines(cm.display, cm.doc, viewport) - if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) - { break } - } - if (!updateDisplayIfNeeded(cm, update)) { break } - updateHeightsInViewport(cm) - var barMeasure = measureForScrollbars(cm) - updateSelection(cm) - updateScrollbars(cm, barMeasure) - setDocumentHeight(cm, barMeasure) - update.force = false - } - - update.signal(cm, "update", cm) - if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { - update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo) - cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo - } -} - -function updateDisplaySimple(cm, viewport) { - var update = new DisplayUpdate(cm, viewport) - if (updateDisplayIfNeeded(cm, update)) { - updateHeightsInViewport(cm) - postUpdateDisplay(cm, update) - var barMeasure = measureForScrollbars(cm) - updateSelection(cm) - updateScrollbars(cm, barMeasure) - setDocumentHeight(cm, barMeasure) - update.finish() - } -} - -// Sync the actual display DOM structure with display.view, removing -// nodes for lines that are no longer in view, and creating the ones -// that are not there yet, and updating the ones that are out of -// date. -function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers - var container = display.lineDiv, cur = container.firstChild - - function rm(node) { - var next = node.nextSibling - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) - { node.style.display = "none" } - else - { node.parentNode.removeChild(node) } - return next - } - - var view = display.view, lineN = display.viewFrom - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i] - if (lineView.hidden) { - } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims) - container.insertBefore(node, cur) - } else { // Already drawn - while (cur != lineView.node) { cur = rm(cur) } - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false } - updateLineForChanges(cm, lineView, lineN, dims) - } - if (updateNumber) { - removeChildren(lineView.lineNumber) - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))) - } - cur = lineView.node.nextSibling - } - lineN += lineView.size - } - while (cur) { cur = rm(cur) } -} - -function updateGutterSpace(cm) { - var width = cm.display.gutters.offsetWidth - cm.display.sizer.style.marginLeft = width + "px" -} - -function setDocumentHeight(cm, measure) { - cm.display.sizer.style.minHeight = measure.docHeight + "px" - cm.display.heightForcer.style.top = measure.docHeight + "px" - cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px" -} - -// Rebuild the gutter elements, ensure the margin to the left of the -// code matches their width. -function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters - removeChildren(gutters) - var i = 0 - for (; i < specs.length; ++i) { - var gutterClass = specs[i] - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)) - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt - gElt.style.width = (cm.display.lineNumWidth || 1) + "px" - } - } - gutters.style.display = i ? "" : "none" - updateGutterSpace(cm) -} - -// Make sure the gutters options contains the element -// "CodeMirror-linenumbers" when the lineNumbers option is true. -function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers") - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]) - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0) - options.gutters.splice(found, 1) - } -} - -var wheelSamples = 0; -var wheelPixelsPerUnit = null; -// Fill in a browser-detected starting value on browsers where we -// know one. These don't have to be accurate -- the result of them -// being wrong would just be a slight flicker on the first wheel -// scroll (if it is large enough). -if (ie) { wheelPixelsPerUnit = -.53 } -else if (gecko) { wheelPixelsPerUnit = 15 } -else if (chrome) { wheelPixelsPerUnit = -.7 } -else if (safari) { wheelPixelsPerUnit = -1/3 } - -function wheelEventDelta(e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail } - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail } - else if (dy == null) { dy = e.wheelDelta } - return {x: dx, y: dy} -} -function wheelEventPixels(e) { - var delta = wheelEventDelta(e) - delta.x *= wheelPixelsPerUnit - delta.y *= wheelPixelsPerUnit - return delta -} - -function onScrollWheel(cm, e) { - var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y - - var display = cm.display, scroll = display.scroller - // Quit if there's nothing to scroll here - var canScrollX = scroll.scrollWidth > scroll.clientWidth - var canScrollY = scroll.scrollHeight > scroll.clientHeight - if (!(dx && canScrollX || dy && canScrollY)) { return } - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur - break outer - } - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy && canScrollY) - { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) } - setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit)) - // Only prevent default scrolling if vertical scrolling is - // actually possible. Otherwise, it causes vertical scroll - // jitter on OSX trackpads when deltaX is small and deltaY - // is large (issue #3579) - if (!dy || (dy && canScrollY)) - { e_preventDefault(e) } - display.wheelStartX = null // Abort measurement, if in progress - return - } - - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight - if (pixels < 0) { top = Math.max(0, top + pixels - 50) } - else { bot = Math.min(cm.doc.height, bot + pixels + 50) } - updateDisplaySimple(cm, {top: top, bottom: bot}) - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop - display.wheelDX = dx; display.wheelDY = dy - setTimeout(function () { - if (display.wheelStartX == null) { return } - var movedX = scroll.scrollLeft - display.wheelStartX - var movedY = scroll.scrollTop - display.wheelStartY - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX) - display.wheelStartX = display.wheelStartY = null - if (!sample) { return } - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1) - ++wheelSamples - }, 200) - } else { - display.wheelDX += dx; display.wheelDY += dy - } - } -} - -// Selection objects are immutable. A new one is created every time -// the selection changes. A selection is one or more non-overlapping -// (and non-touching) ranges, sorted, and an integer that indicates -// which one is the primary selection (the one that's scrolled into -// view, that getCursor returns, etc). -var Selection = function(ranges, primIndex) { - this.ranges = ranges - this.primIndex = primIndex -}; - -Selection.prototype.primary = function () { return this.ranges[this.primIndex] }; - -Selection.prototype.equals = function (other) { - var this$1 = this; - - if (other == this) { return true } - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false } - for (var i = 0; i < this.ranges.length; i++) { - var here = this$1.ranges[i], there = other.ranges[i] - if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false } - } - return true -}; - -Selection.prototype.deepCopy = function () { - var this$1 = this; - - var out = [] - for (var i = 0; i < this.ranges.length; i++) - { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)) } - return new Selection(out, this.primIndex) -}; - -Selection.prototype.somethingSelected = function () { - var this$1 = this; - - for (var i = 0; i < this.ranges.length; i++) - { if (!this$1.ranges[i].empty()) { return true } } - return false -}; - -Selection.prototype.contains = function (pos, end) { - var this$1 = this; - - if (!end) { end = pos } - for (var i = 0; i < this.ranges.length; i++) { - var range = this$1.ranges[i] - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) - { return i } - } - return -1 -}; - -var Range = function(anchor, head) { - this.anchor = anchor; this.head = head -}; - -Range.prototype.from = function () { return minPos(this.anchor, this.head) }; -Range.prototype.to = function () { return maxPos(this.anchor, this.head) }; -Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch }; - -// Take an unsorted, potentially overlapping set of ranges, and -// build a selection out of it. 'Consumes' ranges array (modifying -// it). -function normalizeSelection(ranges, primIndex) { - var prim = ranges[primIndex] - ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }) - primIndex = indexOf(ranges, prim) - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1] - if (cmp(prev.to(), cur.from()) >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()) - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head - if (i <= primIndex) { --primIndex } - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)) - } - } - return new Selection(ranges, primIndex) -} - -function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0) -} - -// Compute the position of the end of a change (its 'to' property -// refers to the pre-change end). -function changeEnd(change) { - if (!change.text) { return change.to } - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)) -} - -// Adjust a position to refer to the post-change position of the -// same text, or the end of the change if the change covers it. -function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) { return pos } - if (cmp(pos, change.to) <= 0) { return changeEnd(change) } - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch - if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch } - return Pos(line, ch) -} - -function computeSelAfterChange(doc, change) { - var out = [] - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i] - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))) - } - return normalizeSelection(out, doc.sel.primIndex) -} - -function offsetPos(pos, old, nw) { - if (pos.line == old.line) - { return Pos(nw.line, pos.ch - old.ch + nw.ch) } - else - { return Pos(nw.line + (pos.line - old.line), pos.ch) } -} - -// Used by replaceSelections to allow moving the selection to the -// start or around the replaced test. Hint may be "start" or "around". -function computeReplacedSel(doc, changes, hint) { - var out = [] - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev - for (var i = 0; i < changes.length; i++) { - var change = changes[i] - var from = offsetPos(change.from, oldPrev, newPrev) - var to = offsetPos(changeEnd(change), oldPrev, newPrev) - oldPrev = change.to - newPrev = to - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0 - out[i] = new Range(inv ? to : from, inv ? from : to) - } else { - out[i] = new Range(from, from) - } - } - return new Selection(out, doc.sel.primIndex) -} - -// Used to get the editor into a consistent state again when options change. - -function loadMode(cm) { - cm.doc.mode = getMode(cm.options, cm.doc.modeOption) - resetModeState(cm) -} - -function resetModeState(cm) { - cm.doc.iter(function (line) { - if (line.stateAfter) { line.stateAfter = null } - if (line.styles) { line.styles = null } - }) - cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first - startWorker(cm, 100) - cm.state.modeGen++ - if (cm.curOp) { regChange(cm) } -} - -// DOCUMENT DATA STRUCTURE - -// By default, updates that start and end at the beginning of a line -// are treated specially, in order to make the association of line -// widgets and marker elements with the text behave more intuitive. -function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore) -} - -// Perform a change on the document data structure. -function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) {return markedSpans ? markedSpans[n] : null} - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight) - signalLater(line, "change", line, change) - } - function linesFor(start, end) { - var result = [] - for (var i = start; i < end; ++i) - { result.push(new Line(text[i], spansFor(i), estimateHeight)) } - return result - } - - var from = change.from, to = change.to, text = change.text - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line) - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line - - // Adjust the line structure - if (change.full) { - doc.insert(0, linesFor(0, text.length)) - doc.remove(text.length, doc.size - text.length) - } else if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - var added = linesFor(0, text.length - 1) - update(lastLine, lastLine.text, lastSpans) - if (nlines) { doc.remove(from.line, nlines) } - if (added.length) { doc.insert(from.line, added) } - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans) - } else { - var added$1 = linesFor(1, text.length - 1) - added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)) - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) - doc.insert(from.line + 1, added$1) - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)) - doc.remove(from.line + 1, nlines) - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans) - var added$2 = linesFor(1, text.length - 1) - if (nlines > 1) { doc.remove(from.line + 1, nlines - 1) } - doc.insert(from.line + 1, added$2) - } - - signalLater(doc, "change", doc, change) -} - -// Call f for all linked documents. -function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i] - if (rel.doc == skip) { continue } - var shared = sharedHist && rel.sharedHist - if (sharedHistOnly && !shared) { continue } - f(rel.doc, shared) - propagate(rel.doc, doc, shared) - } } - } - propagate(doc, null, true) -} - -// Attach a document to an editor. -function attachDoc(cm, doc) { - if (doc.cm) { throw new Error("This document is already in use.") } - cm.doc = doc - doc.cm = cm - estimateLineHeights(cm) - loadMode(cm) - setDirectionClass(cm) - if (!cm.options.lineWrapping) { findMaxLine(cm) } - cm.options.mode = doc.modeOption - regChange(cm) -} - -function setDirectionClass(cm) { - ;(cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl") -} - -function directionChanged(cm) { - runInOp(cm, function () { - setDirectionClass(cm) - regChange(cm) - }) -} - -function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = [] - this.undoDepth = Infinity - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0 - this.lastOp = this.lastSelOp = null - this.lastOrigin = this.lastSelOrigin = null - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1 -} - -// Create a history change event from an updateDoc-style change -// object. -function historyChangeFromChange(doc, change) { - var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)} - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1) - linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true) - return histChange -} - -// Pop all selection events off the end of a history array. Stop at -// a change event. -function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array) - if (last.ranges) { array.pop() } - else { break } - } -} - -// Find the top change event in the history. Pop off selection -// events that are in the way. -function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done) - return lst(hist.done) - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done) - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop() - return lst(hist.done) - } -} - -// Register a change in the history. Merges changes that are within -// a single operation, or are close together with an origin that -// allows merging (starting with "+") into a single event. -function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history - hist.undone.length = 0 - var time = +new Date, cur - var last - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - last = lst(cur.changes) - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change) - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)) - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done) - if (!before || !before.ranges) - { pushSelectionToHistory(doc.sel, hist.done) } - cur = {changes: [historyChangeFromChange(doc, change)], - generation: hist.generation} - hist.done.push(cur) - while (hist.done.length > hist.undoDepth) { - hist.done.shift() - if (!hist.done[0].ranges) { hist.done.shift() } - } - } - hist.done.push(selAfter) - hist.generation = ++hist.maxGeneration - hist.lastModTime = hist.lastSelTime = time - hist.lastOp = hist.lastSelOp = opId - hist.lastOrigin = hist.lastSelOrigin = change.origin - - if (!last) { signal(doc, "historyAdded") } -} - -function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0) - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500) -} - -// Called whenever the selection changes, sets the new selection as -// the pending selection in the history, and pushes the old pending -// selection into the 'done' array when it was significantly -// different (in number of selected ranges, emptiness, or time). -function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastSelOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) - { hist.done[hist.done.length - 1] = sel } - else - { pushSelectionToHistory(sel, hist.done) } - - hist.lastSelTime = +new Date - hist.lastSelOrigin = origin - hist.lastSelOp = opId - if (options && options.clearRedo !== false) - { clearSelectionEvents(hist.undone) } -} - -function pushSelectionToHistory(sel, dest) { - var top = lst(dest) - if (!(top && top.ranges && top.equals(sel))) - { dest.push(sel) } -} - -// Used to store marked span information in the history. -function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0 - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { - if (line.markedSpans) - { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans } - ++n - }) -} - -// When un/re-doing restores text containing marked spans, those -// that have been explicitly cleared should not be restored. -function removeClearedSpans(spans) { - if (!spans) { return null } - var out - for (var i = 0; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i) } } - else if (out) { out.push(spans[i]) } - } - return !out ? spans : out.length ? out : null -} - -// Retrieve and filter the old marked spans stored in a change event. -function getOldSpans(doc, change) { - var found = change["spans_" + doc.id] - if (!found) { return null } - var nw = [] - for (var i = 0; i < change.text.length; ++i) - { nw.push(removeClearedSpans(found[i])) } - return nw -} - -// Used for un/re-doing changes from the history. Combines the -// result of computing the existing spans with the set of spans that -// existed in the history (so that deleting around a span and then -// undoing brings back the span). -function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change) - var stretched = stretchSpansOverChange(doc, change) - if (!old) { return stretched } - if (!stretched) { return old } - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i] - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j] - for (var k = 0; k < oldCur.length; ++k) - { if (oldCur[k].marker == span.marker) { continue spans } } - oldCur.push(span) - } - } else if (stretchCur) { - old[i] = stretchCur - } - } - return old -} - -// Used both to provide a JSON-safe object in .getHistory, and, when -// detaching a document, to split the history in two -function copyHistoryArray(events, newGroup, instantiateSel) { - var copy = [] - for (var i = 0; i < events.length; ++i) { - var event = events[i] - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event) - continue - } - var changes = event.changes, newChanges = [] - copy.push({changes: newChanges}) - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m = (void 0) - newChanges.push({from: change.from, to: change.to, text: change.text}) - if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop] - delete change[prop] - } - } } } - } - } - return copy -} - -// The 'scroll' parameter given to many of these indicated whether -// the new cursor position should be scrolled into view after -// modifying the selection. - -// If shift is held or the extend flag is set, extends a range to -// include a given position (and optionally a second position). -// Otherwise, simply returns the range between the given positions. -// Used for cursor motion and such. -function extendRange(range, head, other, extend) { - if (extend) { - var anchor = range.anchor - if (other) { - var posBefore = cmp(head, anchor) < 0 - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head - head = other - } else if (posBefore != (cmp(head, other) < 0)) { - head = other - } - } - return new Range(anchor, head) - } else { - return new Range(other || head, head) - } -} - -// Extend the primary selection range, discard the rest. -function extendSelection(doc, head, other, options, extend) { - if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend) } - setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options) -} - -// Extend all selections (pos is an array of selections with length -// equal the number of selections) -function extendSelections(doc, heads, options) { - var out = [] - var extend = doc.cm && (doc.cm.display.shift || doc.extend) - for (var i = 0; i < doc.sel.ranges.length; i++) - { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend) } - var newSel = normalizeSelection(out, doc.sel.primIndex) - setSelection(doc, newSel, options) -} - -// Updates a single range in the selection. -function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0) - ranges[i] = range - setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options) -} - -// Reset the selection to a single range. -function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options) -} - -// Give beforeSelectionChange handlers a change to influence a -// selection update. -function filterSelectionChange(doc, sel, options) { - var obj = { - ranges: sel.ranges, - update: function(ranges) { - var this$1 = this; - - this.ranges = [] - for (var i = 0; i < ranges.length; i++) - { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)) } - }, - origin: options && options.origin - } - signal(doc, "beforeSelectionChange", doc, obj) - if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj) } - if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) } - else { return sel } -} - -function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done) - if (last && last.ranges) { - done[done.length - 1] = sel - setSelectionNoUndo(doc, sel, options) - } else { - setSelection(doc, sel, options) - } -} - -// Set a new selection. -function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options) - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options) -} - -function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) - { sel = filterSelectionChange(doc, sel, options) } - - var bias = options && options.bias || - (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1) - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)) - - if (!(options && options.scroll === false) && doc.cm) - { ensureCursorVisible(doc.cm) } -} - -function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) { return } - - doc.sel = sel - - if (doc.cm) { - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true - signalCursorActivity(doc.cm) - } - signalLater(doc, "cursorActivity", doc) -} - -// Verify that the selection does not partially select any atomic -// marked ranges. -function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false)) -} - -// Return a selection that does not partially select any atomic -// ranges. -function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i] - var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i] - var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear) - var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear) - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) { out = sel.ranges.slice(0, i) } - out[i] = new Range(newAnchor, newHead) - } - } - return out ? normalizeSelection(out, sel.primIndex) : sel -} - -function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { - var line = getLine(doc, pos.line) - if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter") - if (m.explicitlyCleared) { - if (!line.markedSpans) { break } - else {--i; continue} - } - } - if (!m.atomic) { continue } - - if (oldPos) { - var near = m.find(dir < 0 ? 1 : -1), diff = (void 0) - if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) - { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null) } - if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) - { return skipAtomicInner(doc, near, pos, dir, mayClear) } - } - - var far = m.find(dir < 0 ? -1 : 1) - if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) - { far = movePos(doc, far, dir, far.line == pos.line ? line : null) } - return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null - } - } } - return pos -} - -// Ensure a given position is not inside an atomic range. -function skipAtomic(doc, pos, oldPos, bias, mayClear) { - var dir = bias || 1 - var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || - skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)) - if (!found) { - doc.cantEdit = true - return Pos(doc.first, 0) - } - return found -} - -function movePos(doc, pos, dir, line) { - if (dir < 0 && pos.ch == 0) { - if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) } - else { return null } - } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { - if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) } - else { return null } - } else { - return new Pos(pos.line, pos.ch + dir) - } -} - -function selectAll(cm) { - cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll) -} - -// UPDATING - -// Allow "beforeChange" event handlers to influence a change -function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function () { return obj.canceled = true; } - } - if (update) { obj.update = function (from, to, text, origin) { - if (from) { obj.from = clipPos(doc, from) } - if (to) { obj.to = clipPos(doc, to) } - if (text) { obj.text = text } - if (origin !== undefined) { obj.origin = origin } - } } - signal(doc, "beforeChange", doc, obj) - if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj) } - - if (obj.canceled) { return null } - return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin} -} - -// Apply a change to a document, and add it to the document's -// history, and propagating it to all linked documents. -function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) } - if (doc.cm.state.suppressEdits) { return } - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true) - if (!change) { return } - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to) - if (split) { - for (var i = split.length - 1; i >= 0; --i) - { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}) } - } else { - makeChangeInner(doc, change) - } -} - -function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return } - var selAfter = computeSelAfterChange(doc, change) - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN) - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)) - var rebased = [] - - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change) - rebased.push(doc.history) - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)) - }) -} - -// Revert a change stored in a document's history. -function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return } - - var hist = doc.history, event, selAfter = doc.sel - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done - - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - var i = 0 - for (; i < source.length; i++) { - event = source[i] - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) - { break } - } - if (i == source.length) { return } - hist.lastOrigin = hist.lastSelOrigin = null - - for (;;) { - event = source.pop() - if (event.ranges) { - pushSelectionToHistory(event, dest) - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, {clearRedo: false}) - return - } - selAfter = event - } - else { break } - } - - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = [] - pushSelectionToHistory(selAfter, dest) - dest.push({changes: antiChanges, generation: hist.generation}) - hist.generation = event.generation || ++hist.maxGeneration - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange") - - var loop = function ( i ) { - var change = event.changes[i] - change.origin = type - if (filter && !filterChange(doc, change, false)) { - source.length = 0 - return {} - } - - antiChanges.push(historyChangeFromChange(doc, change)) - - var after = i ? computeSelAfterChange(doc, change) : lst(source) - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)) - if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) } - var rebased = [] - - // Propagate to the linked documents - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change) - rebased.push(doc.history) - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)) - }) - }; - - for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) { - var returned = loop( i$1 ); - - if ( returned ) return returned.v; - } -} - -// Sub-views need their line numbers shifted when text is added -// above or below them in the parent document. -function shiftDoc(doc, distance) { - if (distance == 0) { return } - doc.first += distance - doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range( - Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch) - ); }), doc.sel.primIndex) - if (doc.cm) { - regChange(doc.cm, doc.first, doc.first - distance, distance) - for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) - { regLineChange(doc.cm, l, "gutter") } - } -} - -// More lower-level change function, handling only a single document -// (not linked ones). -function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) } - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)) - return - } - if (change.from.line > doc.lastLine()) { return } - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line) - shiftDoc(doc, shift) - change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin} - } - var last = doc.lastLine() - if (change.to.line > last) { - change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin} - } - - change.removed = getBetween(doc, change.from, change.to) - - if (!selAfter) { selAfter = computeSelAfterChange(doc, change) } - if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans) } - else { updateDoc(doc, change, spans) } - setSelectionNoUndo(doc, selAfter, sel_dontScroll) -} - -// Handle the interaction of a change to a document with the editor -// that this document is part of. -function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to - - var recomputeMaxLength = false, checkWidthStart = from.line - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))) - doc.iter(checkWidthStart, to.line + 1, function (line) { - if (line == display.maxLine) { - recomputeMaxLength = true - return true - } - }) - } - - if (doc.sel.contains(change.from, change.to) > -1) - { signalCursorActivity(cm) } - - updateDoc(doc, change, spans, estimateHeight(cm)) - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function (line) { - var len = lineLength(line) - if (len > display.maxLineLength) { - display.maxLine = line - display.maxLineLength = len - display.maxLineChanged = true - recomputeMaxLength = false - } - }) - if (recomputeMaxLength) { cm.curOp.updateMaxLine = true } - } - - retreatFrontier(doc, from.line) - startWorker(cm, 400) - - var lendiff = change.text.length - (to.line - from.line) - 1 - // Remember that these lines changed, for updating the display - if (change.full) - { regChange(cm) } - else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) - { regLineChange(cm, from.line, "text") } - else - { regChange(cm, from.line, to.line + 1, lendiff) } - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change") - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - } - if (changeHandler) { signalLater(cm, "change", cm, obj) } - if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) } - } - cm.display.selForContextMenu = null -} - -function replaceRange(doc, code, from, to, origin) { - if (!to) { to = from } - if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp } - if (typeof code == "string") { code = doc.splitLines(code) } - makeChange(doc, {from: from, to: to, text: code, origin: origin}) -} - -// Rebasing/resetting history to deal with externally-sourced changes - -function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff - } else if (from < pos.line) { - pos.line = from - pos.ch = 0 - } -} - -// Tries to rebase an array of history events given a change in the -// document. If the change touches the same lines as the event, the -// event, and everything 'behind' it, is discarded. If the change is -// before the event, the event's positions are updated. Uses a -// copy-on-write scheme for the positions, to avoid having to -// reallocate them all on every rebase, but also avoid problems with -// shared position objects being unsafely updated. -function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff) - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff) - } - continue - } - for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) { - var cur = sub.changes[j$1] - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch) - cur.to = Pos(cur.to.line + diff, cur.to.ch) - } else if (from <= cur.to.line) { - ok = false - break - } - } - if (!ok) { - array.splice(0, i + 1) - i = 0 - } - } -} - -function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1 - rebaseHistArray(hist.done, from, to, diff) - rebaseHistArray(hist.undone, from, to, diff) -} - -// Utility for applying a change to a line by handle or number, -// returning the number and optionally registering the line as -// changed. -function changeLine(doc, handle, changeType, op) { - var no = handle, line = handle - if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)) } - else { no = lineNo(handle) } - if (no == null) { return null } - if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType) } - return line -} - -// The document is represented as a BTree consisting of leaves, with -// chunk of lines in them, and branches, with up to ten leaves or -// other branch nodes below them. The top node is always a branch -// node, and is the document object itself (meaning it has -// additional methods and properties). -// -// All nodes have parent links. The tree is used both to go from -// line numbers to line objects, and to go from objects to numbers. -// It also indexes by height, and is used to convert between height -// and line object, and to find the total height of the document. -// -// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - -function LeafChunk(lines) { - var this$1 = this; - - this.lines = lines - this.parent = null - var height = 0 - for (var i = 0; i < lines.length; ++i) { - lines[i].parent = this$1 - height += lines[i].height - } - this.height = height -} - -LeafChunk.prototype = { - chunkSize: function chunkSize() { return this.lines.length }, - - // Remove the n lines at offset 'at'. - removeInner: function removeInner(at, n) { - var this$1 = this; - - for (var i = at, e = at + n; i < e; ++i) { - var line = this$1.lines[i] - this$1.height -= line.height - cleanUpLine(line) - signalLater(line, "delete") - } - this.lines.splice(at, n) - }, - - // Helper used to collapse a small branch into a single leaf. - collapse: function collapse(lines) { - lines.push.apply(lines, this.lines) - }, - - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function insertInner(at, lines, height) { - var this$1 = this; - - this.height += height - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)) - for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 } - }, - - // Used to iterate over a part of the tree. - iterN: function iterN(at, n, op) { - var this$1 = this; - - for (var e = at + n; at < e; ++at) - { if (op(this$1.lines[at])) { return true } } - } -} - -function BranchChunk(children) { - var this$1 = this; - - this.children = children - var size = 0, height = 0 - for (var i = 0; i < children.length; ++i) { - var ch = children[i] - size += ch.chunkSize(); height += ch.height - ch.parent = this$1 - } - this.size = size - this.height = height - this.parent = null -} - -BranchChunk.prototype = { - chunkSize: function chunkSize() { return this.size }, - - removeInner: function removeInner(at, n) { - var this$1 = this; - - this.size -= n - for (var i = 0; i < this.children.length; ++i) { - var child = this$1.children[i], sz = child.chunkSize() - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height - child.removeInner(at, rm) - this$1.height -= oldHeight - child.height - if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null } - if ((n -= rm) == 0) { break } - at = 0 - } else { at -= sz } - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = [] - this.collapse(lines) - this.children = [new LeafChunk(lines)] - this.children[0].parent = this - } - }, - - collapse: function collapse(lines) { - var this$1 = this; - - for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) } - }, - - insertInner: function insertInner(at, lines, height) { - var this$1 = this; - - this.size += lines.length - this.height += height - for (var i = 0; i < this.children.length; ++i) { - var child = this$1.children[i], sz = child.chunkSize() - if (at <= sz) { - child.insertInner(at, lines, height) - if (child.lines && child.lines.length > 50) { - // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. - // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. - var remaining = child.lines.length % 25 + 25 - for (var pos = remaining; pos < child.lines.length;) { - var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)) - child.height -= leaf.height - this$1.children.splice(++i, 0, leaf) - leaf.parent = this$1 - } - child.lines = child.lines.slice(0, remaining) - this$1.maybeSpill() - } - break - } - at -= sz - } - }, - - // When a node has grown, check whether it should be split. - maybeSpill: function maybeSpill() { - if (this.children.length <= 10) { return } - var me = this - do { - var spilled = me.children.splice(me.children.length - 5, 5) - var sibling = new BranchChunk(spilled) - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children) - copy.parent = me - me.children = [copy, sibling] - me = copy - } else { - me.size -= sibling.size - me.height -= sibling.height - var myIndex = indexOf(me.parent.children, me) - me.parent.children.splice(myIndex + 1, 0, sibling) - } - sibling.parent = me.parent - } while (me.children.length > 10) - me.parent.maybeSpill() - }, - - iterN: function iterN(at, n, op) { - var this$1 = this; - - for (var i = 0; i < this.children.length; ++i) { - var child = this$1.children[i], sz = child.chunkSize() - if (at < sz) { - var used = Math.min(n, sz - at) - if (child.iterN(at, used, op)) { return true } - if ((n -= used) == 0) { break } - at = 0 - } else { at -= sz } - } - } -} - -// Line widgets are block elements displayed above or below a line. - -var LineWidget = function(doc, node, options) { - var this$1 = this; - - if (options) { for (var opt in options) { if (options.hasOwnProperty(opt)) - { this$1[opt] = options[opt] } } } - this.doc = doc - this.node = node -}; - -LineWidget.prototype.clear = function () { - var this$1 = this; - - var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line) - if (no == null || !ws) { return } - for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1) } } - if (!ws.length) { line.widgets = null } - var height = widgetHeight(this) - updateLineHeight(line, Math.max(0, line.height - height)) - if (cm) { - runInOp(cm, function () { - adjustScrollWhenAboveVisible(cm, line, -height) - regLineChange(cm, no, "widget") - }) - signalLater(cm, "lineWidgetCleared", cm, this, no) - } -}; - -LineWidget.prototype.changed = function () { - var this$1 = this; - - var oldH = this.height, cm = this.doc.cm, line = this.line - this.height = null - var diff = widgetHeight(this) - oldH - if (!diff) { return } - updateLineHeight(line, line.height + diff) - if (cm) { - runInOp(cm, function () { - cm.curOp.forceUpdate = true - adjustScrollWhenAboveVisible(cm, line, diff) - signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line)) - }) - } -}; -eventMixin(LineWidget) - -function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) - { addToScrollTop(cm, diff) } -} - -function addLineWidget(doc, handle, node, options) { - var widget = new LineWidget(doc, node, options) - var cm = doc.cm - if (cm && widget.noHScroll) { cm.display.alignWidgets = true } - changeLine(doc, handle, "widget", function (line) { - var widgets = line.widgets || (line.widgets = []) - if (widget.insertAt == null) { widgets.push(widget) } - else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget) } - widget.line = line - if (cm && !lineIsHidden(doc, line)) { - var aboveVisible = heightAtLine(line) < doc.scrollTop - updateLineHeight(line, line.height + widgetHeight(widget)) - if (aboveVisible) { addToScrollTop(cm, widget.height) } - cm.curOp.forceUpdate = true - } - return true - }) - signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)) - return widget -} - -// TEXTMARKERS - -// Created with markText and setBookmark methods. A TextMarker is a -// handle that can be used to clear or find a marked position in the -// document. Line objects hold arrays (markedSpans) containing -// {from, to, marker} object pointing to such marker objects, and -// indicating that such a marker is present on that line. Multiple -// lines may point to the same marker when it spans across lines. -// The spans will have null for their from/to properties when the -// marker continues beyond the start/end of the line. Markers have -// links back to the lines they currently touch. - -// Collapsed markers have unique ids, in order to be able to order -// them, which is needed for uniquely determining an outer marker -// when they overlap (they may nest, but not partially overlap). -var nextMarkerId = 0 - -var TextMarker = function(doc, type) { - this.lines = [] - this.type = type - this.doc = doc - this.id = ++nextMarkerId -}; - -// Clear the marker. -TextMarker.prototype.clear = function () { - var this$1 = this; - - if (this.explicitlyCleared) { return } - var cm = this.doc.cm, withOp = cm && !cm.curOp - if (withOp) { startOperation(cm) } - if (hasHandler(this, "clear")) { - var found = this.find() - if (found) { signalLater(this, "clear", found.from, found.to) } - } - var min = null, max = null - for (var i = 0; i < this.lines.length; ++i) { - var line = this$1.lines[i] - var span = getMarkedSpanFor(line.markedSpans, this$1) - if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text") } - else if (cm) { - if (span.to != null) { max = lineNo(line) } - if (span.from != null) { min = lineNo(line) } - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span) - if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm) - { updateLineHeight(line, textHeight(cm.display)) } - } - if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) { - var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual) - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual - cm.display.maxLineLength = len - cm.display.maxLineChanged = true - } - } } - - if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1) } - this.lines.length = 0 - this.explicitlyCleared = true - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false - if (cm) { reCheckSelection(cm.doc) } - } - if (cm) { signalLater(cm, "markerCleared", cm, this, min, max) } - if (withOp) { endOperation(cm) } - if (this.parent) { this.parent.clear() } -}; - -// Find the position of the marker in the document. Returns a {from, -// to} object by default. Side can be passed to get a specific side -// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the -// Pos objects returned contain a line object, rather than a line -// number (used to prevent looking up the same line twice). -TextMarker.prototype.find = function (side, lineObj) { - var this$1 = this; - - if (side == null && this.type == "bookmark") { side = 1 } - var from, to - for (var i = 0; i < this.lines.length; ++i) { - var line = this$1.lines[i] - var span = getMarkedSpanFor(line.markedSpans, this$1) - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from) - if (side == -1) { return from } - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to) - if (side == 1) { return to } - } - } - return from && {from: from, to: to} -}; - -// Signals that the marker's widget changed, and surrounding layout -// should be recomputed. -TextMarker.prototype.changed = function () { - var this$1 = this; - - var pos = this.find(-1, true), widget = this, cm = this.doc.cm - if (!pos || !cm) { return } - runInOp(cm, function () { - var line = pos.line, lineN = lineNo(pos.line) - var view = findViewForLine(cm, lineN) - if (view) { - clearLineMeasurementCacheFor(view) - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true - } - cm.curOp.updateMaxLine = true - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height - widget.height = null - var dHeight = widgetHeight(widget) - oldHeight - if (dHeight) - { updateLineHeight(line, line.height + dHeight) } - } - signalLater(cm, "markerChanged", cm, this$1) - }) -}; - -TextMarker.prototype.attachLine = function (line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this) } - } - this.lines.push(line) -}; - -TextMarker.prototype.detachLine = function (line) { - this.lines.splice(indexOf(this.lines, line), 1) - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp - ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this) - } -}; -eventMixin(TextMarker) - -// Create a marker, wire it up to the right lines, and -function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) { return markTextShared(doc, from, to, options, type) } - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) } - - var marker = new TextMarker(doc, type), diff = cmp(from, to) - if (options) { copyObj(options, marker, false) } - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) - { return marker } - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true - marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget") - if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true") } - if (options.insertLeft) { marker.widgetNode.insertLeft = true } - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) - { throw new Error("Inserting collapsed marker partially overlapping an existing one") } - seeCollapsedSpans() - } - - if (marker.addToHistory) - { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN) } - - var curLine = from.line, cm = doc.cm, updateMaxLine - doc.iter(curLine, to.line + 1, function (line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) - { updateMaxLine = true } - if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0) } - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)) - ++curLine - }) - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) { - if (lineIsHidden(doc, line)) { updateLineHeight(line, 0) } - }) } - - if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }) } - - if (marker.readOnly) { - seeReadOnlySpans() - if (doc.history.done.length || doc.history.undone.length) - { doc.clearHistory() } - } - if (marker.collapsed) { - marker.id = ++nextMarkerId - marker.atomic = true - } - if (cm) { - // Sync editor state - if (updateMaxLine) { cm.curOp.updateMaxLine = true } - if (marker.collapsed) - { regChange(cm, from.line, to.line + 1) } - else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) - { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text") } } - if (marker.atomic) { reCheckSelection(cm.doc) } - signalLater(cm, "markerAdded", cm, marker) - } - return marker -} - -// SHARED TEXTMARKERS - -// A shared marker spans multiple linked documents. It is -// implemented as a meta-marker-object controlling multiple normal -// markers. -var SharedTextMarker = function(markers, primary) { - var this$1 = this; - - this.markers = markers - this.primary = primary - for (var i = 0; i < markers.length; ++i) - { markers[i].parent = this$1 } -}; - -SharedTextMarker.prototype.clear = function () { - var this$1 = this; - - if (this.explicitlyCleared) { return } - this.explicitlyCleared = true - for (var i = 0; i < this.markers.length; ++i) - { this$1.markers[i].clear() } - signalLater(this, "clear") -}; - -SharedTextMarker.prototype.find = function (side, lineObj) { - return this.primary.find(side, lineObj) -}; -eventMixin(SharedTextMarker) - -function markTextShared(doc, from, to, options, type) { - options = copyObj(options) - options.shared = false - var markers = [markText(doc, from, to, options, type)], primary = markers[0] - var widget = options.widgetNode - linkedDocs(doc, function (doc) { - if (widget) { options.widgetNode = widget.cloneNode(true) } - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)) - for (var i = 0; i < doc.linked.length; ++i) - { if (doc.linked[i].isParent) { return } } - primary = lst(markers) - }) - return new SharedTextMarker(markers, primary) -} - -function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; }) -} - -function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find() - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to) - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type) - marker.markers.push(subMark) - subMark.parent = marker - } - } -} - -function detachSharedMarkers(markers) { - var loop = function ( i ) { - var marker = markers[i], linked = [marker.primary.doc] - linkedDocs(marker.primary.doc, function (d) { return linked.push(d); }) - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j] - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null - marker.markers.splice(j--, 1) - } - } - }; - - for (var i = 0; i < markers.length; i++) loop( i ); -} - -var nextDocId = 0 -var Doc = function(text, mode, firstLine, lineSep, direction) { - if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) } - if (firstLine == null) { firstLine = 0 } - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]) - this.first = firstLine - this.scrollTop = this.scrollLeft = 0 - this.cantEdit = false - this.cleanGeneration = 1 - this.modeFrontier = this.highlightFrontier = firstLine - var start = Pos(firstLine, 0) - this.sel = simpleSelection(start) - this.history = new History(null) - this.id = ++nextDocId - this.modeOption = mode - this.lineSep = lineSep - this.direction = (direction == "rtl") ? "rtl" : "ltr" - this.extend = false - - if (typeof text == "string") { text = this.splitLines(text) } - updateDoc(this, {from: start, to: start, text: text}) - setSelection(this, simpleSelection(start), sel_dontScroll) -} - -Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function(from, to, op) { - if (op) { this.iterN(from - this.first, to - from, op) } - else { this.iterN(this.first, this.first + this.size, from) } - }, - - // Non-public interface for adding and removing lines. - insert: function(at, lines) { - var height = 0 - for (var i = 0; i < lines.length; ++i) { height += lines[i].height } - this.insertInner(at - this.first, lines, height) - }, - remove: function(at, n) { this.removeInner(at - this.first, n) }, - - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. - - getValue: function(lineSep) { - var lines = getLines(this, this.first, this.first + this.size) - if (lineSep === false) { return lines } - return lines.join(lineSep || this.lineSeparator()) - }, - setValue: docMethodOp(function(code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1 - makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), - text: this.splitLines(code), origin: "setValue", full: true}, true) - if (this.cm) { scrollToCoords(this.cm, 0, 0) } - setSelection(this, simpleSelection(top), sel_dontScroll) - }), - replaceRange: function(code, from, to, origin) { - from = clipPos(this, from) - to = to ? clipPos(this, to) : from - replaceRange(this, code, from, to, origin) - }, - getRange: function(from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)) - if (lineSep === false) { return lines } - return lines.join(lineSep || this.lineSeparator()) - }, - - getLine: function(line) {var l = this.getLineHandle(line); return l && l.text}, - - getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }}, - getLineNumber: function(line) {return lineNo(line)}, - - getLineHandleVisualStart: function(line) { - if (typeof line == "number") { line = getLine(this, line) } - return visualLine(line) - }, - - lineCount: function() {return this.size}, - firstLine: function() {return this.first}, - lastLine: function() {return this.first + this.size - 1}, - - clipPos: function(pos) {return clipPos(this, pos)}, - - getCursor: function(start) { - var range = this.sel.primary(), pos - if (start == null || start == "head") { pos = range.head } - else if (start == "anchor") { pos = range.anchor } - else if (start == "end" || start == "to" || start === false) { pos = range.to() } - else { pos = range.from() } - return pos - }, - listSelections: function() { return this.sel.ranges }, - somethingSelected: function() {return this.sel.somethingSelected()}, - - setCursor: docMethodOp(function(line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options) - }), - setSelection: docMethodOp(function(anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options) - }), - extendSelection: docMethodOp(function(head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options) - }), - extendSelections: docMethodOp(function(heads, options) { - extendSelections(this, clipPosArray(this, heads), options) - }), - extendSelectionsBy: docMethodOp(function(f, options) { - var heads = map(this.sel.ranges, f) - extendSelections(this, clipPosArray(this, heads), options) - }), - setSelections: docMethodOp(function(ranges, primary, options) { - var this$1 = this; - - if (!ranges.length) { return } - var out = [] - for (var i = 0; i < ranges.length; i++) - { out[i] = new Range(clipPos(this$1, ranges[i].anchor), - clipPos(this$1, ranges[i].head)) } - if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex) } - setSelection(this, normalizeSelection(out, primary), options) - }), - addSelection: docMethodOp(function(anchor, head, options) { - var ranges = this.sel.ranges.slice(0) - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))) - setSelection(this, normalizeSelection(ranges, ranges.length - 1), options) - }), - - getSelection: function(lineSep) { - var this$1 = this; - - var ranges = this.sel.ranges, lines - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this$1, ranges[i].from(), ranges[i].to()) - lines = lines ? lines.concat(sel) : sel - } - if (lineSep === false) { return lines } - else { return lines.join(lineSep || this.lineSeparator()) } - }, - getSelections: function(lineSep) { - var this$1 = this; - - var parts = [], ranges = this.sel.ranges - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this$1, ranges[i].from(), ranges[i].to()) - if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()) } - parts[i] = sel - } - return parts - }, - replaceSelection: function(code, collapse, origin) { - var dup = [] - for (var i = 0; i < this.sel.ranges.length; i++) - { dup[i] = code } - this.replaceSelections(dup, collapse, origin || "+input") - }, - replaceSelections: docMethodOp(function(code, collapse, origin) { - var this$1 = this; - - var changes = [], sel = this.sel - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i] - changes[i] = {from: range.from(), to: range.to(), text: this$1.splitLines(code[i]), origin: origin} - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse) - for (var i$1 = changes.length - 1; i$1 >= 0; i$1--) - { makeChange(this$1, changes[i$1]) } - if (newSel) { setSelectionReplaceHistory(this, newSel) } - else if (this.cm) { ensureCursorVisible(this.cm) } - }), - undo: docMethodOp(function() {makeChangeFromHistory(this, "undo")}), - redo: docMethodOp(function() {makeChangeFromHistory(this, "redo")}), - undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true)}), - redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true)}), - - setExtending: function(val) {this.extend = val}, - getExtending: function() {return this.extend}, - - historySize: function() { - var hist = this.history, done = 0, undone = 0 - for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done } } - for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone } } - return {undo: done, redo: undone} - }, - clearHistory: function() {this.history = new History(this.history.maxGeneration)}, - - markClean: function() { - this.cleanGeneration = this.changeGeneration(true) - }, - changeGeneration: function(forceSplit) { - if (forceSplit) - { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null } - return this.history.generation - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration) - }, - - getHistory: function() { - return {done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone)} - }, - setHistory: function(histData) { - var hist = this.history = new History(this.history.maxGeneration) - hist.done = copyHistoryArray(histData.done.slice(0), null, true) - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true) - }, - - setGutterMarker: docMethodOp(function(line, gutterID, value) { - return changeLine(this, line, "gutter", function (line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}) - markers[gutterID] = value - if (!value && isEmpty(markers)) { line.gutterMarkers = null } - return true - }) - }), - - clearGutter: docMethodOp(function(gutterID) { - var this$1 = this; - - this.iter(function (line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - changeLine(this$1, line, "gutter", function () { - line.gutterMarkers[gutterID] = null - if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null } - return true - }) - } - }) - }), - - lineInfo: function(line) { - var n - if (typeof line == "number") { - if (!isLine(this, line)) { return null } - n = line - line = getLine(this, line) - if (!line) { return null } - } else { - n = lineNo(line) - if (n == null) { return null } - } - return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets} - }, - - addLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass" - if (!line[prop]) { line[prop] = cls } - else if (classTest(cls).test(line[prop])) { return false } - else { line[prop] += " " + cls } - return true - }) - }), - removeLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass" - var cur = line[prop] - if (!cur) { return false } - else if (cls == null) { line[prop] = null } - else { - var found = cur.match(classTest(cls)) - if (!found) { return false } - var end = found.index + found[0].length - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null - } - return true - }) - }), - - addLineWidget: docMethodOp(function(handle, node, options) { - return addLineWidget(this, handle, node, options) - }), - removeLineWidget: function(widget) { widget.clear() }, - - markText: function(from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range") - }, - setBookmark: function(pos, options) { - var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared, - handleMouseEvents: options && options.handleMouseEvents} - pos = clipPos(this, pos) - return markText(this, pos, pos, realOpts, "bookmark") - }, - findMarksAt: function(pos) { - pos = clipPos(this, pos) - var markers = [], spans = getLine(this, pos.line).markedSpans - if (spans) { for (var i = 0; i < spans.length; ++i) { - var span = spans[i] - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - { markers.push(span.marker.parent || span.marker) } - } } - return markers - }, - findMarks: function(from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to) - var found = [], lineNo = from.line - this.iter(from.line, to.line + 1, function (line) { - var spans = line.markedSpans - if (spans) { for (var i = 0; i < spans.length; i++) { - var span = spans[i] - if (!(span.to != null && lineNo == from.line && from.ch >= span.to || - span.from == null && lineNo != from.line || - span.from != null && lineNo == to.line && span.from >= to.ch) && - (!filter || filter(span.marker))) - { found.push(span.marker.parent || span.marker) } - } } - ++lineNo - }) - return found - }, - getAllMarks: function() { - var markers = [] - this.iter(function (line) { - var sps = line.markedSpans - if (sps) { for (var i = 0; i < sps.length; ++i) - { if (sps[i].from != null) { markers.push(sps[i].marker) } } } - }) - return markers - }, - - posFromIndex: function(off) { - var ch, lineNo = this.first, sepSize = this.lineSeparator().length - this.iter(function (line) { - var sz = line.text.length + sepSize - if (sz > off) { ch = off; return true } - off -= sz - ++lineNo - }) - return clipPos(this, Pos(lineNo, ch)) - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords) - var index = coords.ch - if (coords.line < this.first || coords.ch < 0) { return 0 } - var sepSize = this.lineSeparator().length - this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value - index += line.text.length + sepSize - }) - return index - }, - - copy: function(copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), - this.modeOption, this.first, this.lineSep, this.direction) - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft - doc.sel = this.sel - doc.extend = false - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth - doc.setHistory(this.getHistory()) - } - return doc - }, - - linkedDoc: function(options) { - if (!options) { options = {} } - var from = this.first, to = this.first + this.size - if (options.from != null && options.from > from) { from = options.from } - if (options.to != null && options.to < to) { to = options.to } - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction) - if (options.sharedHist) { copy.history = this.history - ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}) - copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}] - copySharedMarkers(copy, findSharedMarkers(this)) - return copy - }, - unlinkDoc: function(other) { - var this$1 = this; - - if (other instanceof CodeMirror) { other = other.doc } - if (this.linked) { for (var i = 0; i < this.linked.length; ++i) { - var link = this$1.linked[i] - if (link.doc != other) { continue } - this$1.linked.splice(i, 1) - other.unlinkDoc(this$1) - detachSharedMarkers(findSharedMarkers(this$1)) - break - } } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id] - linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true) - other.history = new History(null) - other.history.done = copyHistoryArray(this.history.done, splitIds) - other.history.undone = copyHistoryArray(this.history.undone, splitIds) - } - }, - iterLinkedDocs: function(f) {linkedDocs(this, f)}, - - getMode: function() {return this.mode}, - getEditor: function() {return this.cm}, - - splitLines: function(str) { - if (this.lineSep) { return str.split(this.lineSep) } - return splitLinesAuto(str) - }, - lineSeparator: function() { return this.lineSep || "\n" }, - - setDirection: docMethodOp(function (dir) { - if (dir != "rtl") { dir = "ltr" } - if (dir == this.direction) { return } - this.direction = dir - this.iter(function (line) { return line.order = null; }) - if (this.cm) { directionChanged(this.cm) } - }) -}) - -// Public alias. -Doc.prototype.eachLine = Doc.prototype.iter - -// Kludge to work around strange IE behavior where it'll sometimes -// re-fire a series of drag-related events right after the drop (#1551) -var lastDrop = 0 - -function onDrop(e) { - var cm = this - clearDragCursor(cm) - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) - { return } - e_preventDefault(e) - if (ie) { lastDrop = +new Date } - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files - if (!pos || cm.isReadOnly()) { return } - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0 - var loadFile = function (file, i) { - if (cm.options.allowDropFileTypes && - indexOf(cm.options.allowDropFileTypes, file.type) == -1) - { return } - - var reader = new FileReader - reader.onload = operation(cm, function () { - var content = reader.result - if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = "" } - text[i] = content - if (++read == n) { - pos = clipPos(cm.doc, pos) - var change = {from: pos, to: pos, - text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), - origin: "paste"} - makeChange(cm.doc, change) - setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))) - } - }) - reader.readAsText(file) - } - for (var i = 0; i < n; ++i) { loadFile(files[i], i) } - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e) - // Ensure the editor is re-focused - setTimeout(function () { return cm.display.input.focus(); }, 20) - return - } - try { - var text$1 = e.dataTransfer.getData("Text") - if (text$1) { - var selected - if (cm.state.draggingText && !cm.state.draggingText.copy) - { selected = cm.listSelections() } - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)) - if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1) - { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag") } } - cm.replaceSelection(text$1, "around", "paste") - cm.display.input.focus() - } - } - catch(e){} - } -} - -function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return } - - e.dataTransfer.setData("Text", cm.getSelection()) - e.dataTransfer.effectAllowed = "copyMove" - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;") - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" - if (presto) { - img.width = img.height = 1 - cm.display.wrapper.appendChild(img) - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop - } - e.dataTransfer.setDragImage(img, 0, 0) - if (presto) { img.parentNode.removeChild(img) } - } -} - -function onDragOver(cm, e) { - var pos = posFromMouse(cm, e) - if (!pos) { return } - var frag = document.createDocumentFragment() - drawSelectionCursor(cm, pos, frag) - if (!cm.display.dragCursor) { - cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors") - cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv) - } - removeChildrenAndAdd(cm.display.dragCursor, frag) -} - -function clearDragCursor(cm) { - if (cm.display.dragCursor) { - cm.display.lineSpace.removeChild(cm.display.dragCursor) - cm.display.dragCursor = null - } -} - -// These must be handled carefully, because naively registering a -// handler for each editor will cause the editors to never be -// garbage collected. - -function forEachCodeMirror(f) { - if (!document.getElementsByClassName) { return } - var byClass = document.getElementsByClassName("CodeMirror") - for (var i = 0; i < byClass.length; i++) { - var cm = byClass[i].CodeMirror - if (cm) { f(cm) } - } -} - -var globalsRegistered = false -function ensureGlobalHandlers() { - if (globalsRegistered) { return } - registerGlobalHandlers() - globalsRegistered = true -} -function registerGlobalHandlers() { - // When the window resizes, we need to refresh active editors. - var resizeTimer - on(window, "resize", function () { - if (resizeTimer == null) { resizeTimer = setTimeout(function () { - resizeTimer = null - forEachCodeMirror(onResize) - }, 100) } - }) - // When the window loses focus, we want to show the editor as blurred - on(window, "blur", function () { return forEachCodeMirror(onBlur); }) -} -// Called when the window resizes -function onResize(cm) { - var d = cm.display - if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) - { return } - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null - d.scrollbarsClipped = false - cm.setSize() -} - -var keyNames = { - 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" -} - -// Number keys -for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i) } -// Alphabetic keys -for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1) } -// Function keys -for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2 } - -var keyMap = {} - -keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" -} -// Note that the save and find-related commands aren't defined by -// default. User code or addons can define them. Unknown commands -// are simply ignored. -keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" -} -// Very basic readline/emacs-style bindings, which are standard on Mac. -keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", - "Ctrl-O": "openLine" -} -keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - fallthrough: ["basic", "emacsy"] -} -keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault - -// KEYMAP DISPATCH - -function normalizeKeyName(name) { - var parts = name.split(/-(?!$)/) - name = parts[parts.length - 1] - var alt, ctrl, shift, cmd - for (var i = 0; i < parts.length - 1; i++) { - var mod = parts[i] - if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true } - else if (/^a(lt)?$/i.test(mod)) { alt = true } - else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true } - else if (/^s(hift)?$/i.test(mod)) { shift = true } - else { throw new Error("Unrecognized modifier name: " + mod) } - } - if (alt) { name = "Alt-" + name } - if (ctrl) { name = "Ctrl-" + name } - if (cmd) { name = "Cmd-" + name } - if (shift) { name = "Shift-" + name } - return name -} - -// This is a kludge to keep keymaps mostly working as raw objects -// (backwards compatibility) while at the same time support features -// like normalization and multi-stroke key bindings. It compiles a -// new normalized keymap, and then updates the old object to reflect -// this. -function normalizeKeyMap(keymap) { - var copy = {} - for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) { - var value = keymap[keyname] - if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue } - if (value == "...") { delete keymap[keyname]; continue } - - var keys = map(keyname.split(" "), normalizeKeyName) - for (var i = 0; i < keys.length; i++) { - var val = (void 0), name = (void 0) - if (i == keys.length - 1) { - name = keys.join(" ") - val = value - } else { - name = keys.slice(0, i + 1).join(" ") - val = "..." - } - var prev = copy[name] - if (!prev) { copy[name] = val } - else if (prev != val) { throw new Error("Inconsistent bindings for " + name) } - } - delete keymap[keyname] - } } - for (var prop in copy) { keymap[prop] = copy[prop] } - return keymap -} - -function lookupKey(key, map, handle, context) { - map = getKeyMap(map) - var found = map.call ? map.call(key, context) : map[key] - if (found === false) { return "nothing" } - if (found === "...") { return "multi" } - if (found != null && handle(found)) { return "handled" } - - if (map.fallthrough) { - if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") - { return lookupKey(key, map.fallthrough, handle, context) } - for (var i = 0; i < map.fallthrough.length; i++) { - var result = lookupKey(key, map.fallthrough[i], handle, context) - if (result) { return result } - } - } -} - -// Modifier key presses don't count as 'real' key presses for the -// purpose of keymap fallthrough. -function isModifierKey(value) { - var name = typeof value == "string" ? value : keyNames[value.keyCode] - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod" -} - -function addModifierNames(name, event, noShift) { - var base = name - if (event.altKey && base != "Alt") { name = "Alt-" + name } - if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name } - if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name } - if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name } - return name -} - -// Look up the name of a key as indicated by an event object. -function keyName(event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) { return false } - var name = keyNames[event.keyCode] - if (name == null || event.altGraphKey) { return false } - return addModifierNames(name, event, noShift) -} - -function getKeyMap(val) { - return typeof val == "string" ? keyMap[val] : val -} - -// Helper for deleting text near the selection(s), used to implement -// backspace, delete, and similar functionality. -function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = [] - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]) - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop() - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from - break - } - } - kill.push(toKill) - } - // Next, remove those actual ranges. - runInOp(cm, function () { - for (var i = kill.length - 1; i >= 0; i--) - { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete") } - ensureCursorVisible(cm) - }) -} - -// Commands are parameter-less actions that can be performed on an -// editor, mostly used for keybindings. -var commands = { - selectAll: selectAll, - singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); }, - killLine: function (cm) { return deleteNearSelection(cm, function (range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length - if (range.head.ch == len && range.head.line < cm.lastLine()) - { return {from: range.head, to: Pos(range.head.line + 1, 0)} } - else - { return {from: range.head, to: Pos(range.head.line, len)} } - } else { - return {from: range.from(), to: range.to()} - } - }); }, - deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({ - from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) - }); }); }, - delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({ - from: Pos(range.from().line, 0), to: range.from() - }); }); }, - delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5 - var leftPos = cm.coordsChar({left: 0, top: top}, "div") - return {from: leftPos, to: range.from()} - }); }, - delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5 - var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") - return {from: range.from(), to: rightPos } - }); }, - undo: function (cm) { return cm.undo(); }, - redo: function (cm) { return cm.redo(); }, - undoSelection: function (cm) { return cm.undoSelection(); }, - redoSelection: function (cm) { return cm.redoSelection(); }, - goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); }, - goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); }, - goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, - {origin: "+move", bias: 1} - ); }, - goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); }, - {origin: "+move", bias: 1} - ); }, - goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, - {origin: "+move", bias: -1} - ); }, - goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5 - return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") - }, sel_move); }, - goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5 - return cm.coordsChar({left: 0, top: top}, "div") - }, sel_move); }, - goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5 - var pos = cm.coordsChar({left: 0, top: top}, "div") - if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) } - return pos - }, sel_move); }, - goLineUp: function (cm) { return cm.moveV(-1, "line"); }, - goLineDown: function (cm) { return cm.moveV(1, "line"); }, - goPageUp: function (cm) { return cm.moveV(-1, "page"); }, - goPageDown: function (cm) { return cm.moveV(1, "page"); }, - goCharLeft: function (cm) { return cm.moveH(-1, "char"); }, - goCharRight: function (cm) { return cm.moveH(1, "char"); }, - goColumnLeft: function (cm) { return cm.moveH(-1, "column"); }, - goColumnRight: function (cm) { return cm.moveH(1, "column"); }, - goWordLeft: function (cm) { return cm.moveH(-1, "word"); }, - goGroupRight: function (cm) { return cm.moveH(1, "group"); }, - goGroupLeft: function (cm) { return cm.moveH(-1, "group"); }, - goWordRight: function (cm) { return cm.moveH(1, "word"); }, - delCharBefore: function (cm) { return cm.deleteH(-1, "char"); }, - delCharAfter: function (cm) { return cm.deleteH(1, "char"); }, - delWordBefore: function (cm) { return cm.deleteH(-1, "word"); }, - delWordAfter: function (cm) { return cm.deleteH(1, "word"); }, - delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); }, - delGroupAfter: function (cm) { return cm.deleteH(1, "group"); }, - indentAuto: function (cm) { return cm.indentSelection("smart"); }, - indentMore: function (cm) { return cm.indentSelection("add"); }, - indentLess: function (cm) { return cm.indentSelection("subtract"); }, - insertTab: function (cm) { return cm.replaceSelection("\t"); }, - insertSoftTab: function (cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from() - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize) - spaces.push(spaceStr(tabSize - col % tabSize)) - } - cm.replaceSelections(spaces) - }, - defaultTab: function (cm) { - if (cm.somethingSelected()) { cm.indentSelection("add") } - else { cm.execCommand("insertTab") } - }, - // Swap the two chars left and right of each selection's head. - // Move cursor behind the two swapped characters afterwards. - // - // Doesn't consider line feeds a character. - // Doesn't scan more than one line above to find a character. - // Doesn't do anything on an empty line. - // Doesn't do anything with non-empty selections. - transposeChars: function (cm) { return runInOp(cm, function () { - var ranges = cm.listSelections(), newSel = [] - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) { continue } - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text - if (line) { - if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1) } - if (cur.ch > 0) { - cur = new Pos(cur.line, cur.ch + 1) - cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), - Pos(cur.line, cur.ch - 2), cur, "+transpose") - } else if (cur.line > cm.doc.first) { - var prev = getLine(cm.doc, cur.line - 1).text - if (prev) { - cur = new Pos(cur.line, 1) - cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + - prev.charAt(prev.length - 1), - Pos(cur.line - 1, prev.length - 1), cur, "+transpose") - } - } - } - newSel.push(new Range(cur, cur)) - } - cm.setSelections(newSel) - }); }, - newlineAndIndent: function (cm) { return runInOp(cm, function () { - var sels = cm.listSelections() - for (var i = sels.length - 1; i >= 0; i--) - { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input") } - sels = cm.listSelections() - for (var i$1 = 0; i$1 < sels.length; i$1++) - { cm.indentLine(sels[i$1].from().line, null, true) } - ensureCursorVisible(cm) - }); }, - openLine: function (cm) { return cm.replaceSelection("\n", "start"); }, - toggleOverwrite: function (cm) { return cm.toggleOverwrite(); } -} - - -function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN) - var visual = visualLine(line) - if (visual != line) { lineN = lineNo(visual) } - return endOfLine(true, cm, visual, lineN, 1) -} -function lineEnd(cm, lineN) { - var line = getLine(cm.doc, lineN) - var visual = visualLineEnd(line) - if (visual != line) { lineN = lineNo(visual) } - return endOfLine(true, cm, line, lineN, -1) -} -function lineStartSmart(cm, pos) { - var start = lineStart(cm, pos.line) - var line = getLine(cm.doc, start.line) - var order = getOrder(line, cm.doc.direction) - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)) - var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch - return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky) - } - return start -} - -// Run a handler that was bound to a key. -function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound] - if (!bound) { return false } - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - cm.display.input.ensurePolled() - var prevShift = cm.display.shift, done = false - try { - if (cm.isReadOnly()) { cm.state.suppressEdits = true } - if (dropShift) { cm.display.shift = false } - done = bound(cm) != Pass - } finally { - cm.display.shift = prevShift - cm.state.suppressEdits = false - } - return done -} - -function lookupKeyForEditor(cm, name, handle) { - for (var i = 0; i < cm.state.keyMaps.length; i++) { - var result = lookupKey(name, cm.state.keyMaps[i], handle, cm) - if (result) { return result } - } - return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) - || lookupKey(name, cm.options.keyMap, handle, cm) -} - -// Note that, despite the name, this function is also used to check -// for bound mouse clicks. - -var stopSeq = new Delayed -function dispatchKey(cm, name, e, handle) { - var seq = cm.state.keySeq - if (seq) { - if (isModifierKey(name)) { return "handled" } - stopSeq.set(50, function () { - if (cm.state.keySeq == seq) { - cm.state.keySeq = null - cm.display.input.reset() - } - }) - name = seq + " " + name - } - var result = lookupKeyForEditor(cm, name, handle) - - if (result == "multi") - { cm.state.keySeq = name } - if (result == "handled") - { signalLater(cm, "keyHandled", cm, name, e) } - - if (result == "handled" || result == "multi") { - e_preventDefault(e) - restartBlink(cm) - } - - if (seq && !result && /\'$/.test(name)) { - e_preventDefault(e) - return true - } - return !!result -} - -// Handle a key from the keydown event. -function handleKeyBinding(cm, e) { - var name = keyName(e, true) - if (!name) { return false } - - if (e.shiftKey && !cm.state.keySeq) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) - || dispatchKey(cm, name, e, function (b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - { return doHandleBinding(cm, b) } - }) - } else { - return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }) - } -} - -// Handle a key from the keypress event -function handleCharBinding(cm, e, ch) { - return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); }) -} - -var lastStoppedKey = null -function onKeyDown(e) { - var cm = this - cm.curOp.focus = activeElt() - if (signalDOMEvent(cm, e)) { return } - // IE does strange things with escape. - if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false } - var code = e.keyCode - cm.display.shift = code == 16 || e.shiftKey - var handled = handleKeyBinding(cm, e) - if (presto) { - lastStoppedKey = handled ? code : null - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - { cm.replaceSelection("", null, "cut") } - } - - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) - { showCrossHair(cm) } -} - -function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv - addClass(lineDiv, "CodeMirror-crosshair") - - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair") - off(document, "keyup", up) - off(document, "mouseover", up) - } - } - on(document, "keyup", up) - on(document, "mouseover", up) -} - -function onKeyUp(e) { - if (e.keyCode == 16) { this.doc.sel.shift = false } - signalDOMEvent(this, e) -} - -function onKeyPress(e) { - var cm = this - if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return } - var keyCode = e.keyCode, charCode = e.charCode - if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return} - if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return } - var ch = String.fromCharCode(charCode == null ? keyCode : charCode) - // Some browsers fire keypress events for backspace - if (ch == "\x08") { return } - if (handleCharBinding(cm, e, ch)) { return } - cm.display.input.onKeyPress(e) -} - -var DOUBLECLICK_DELAY = 400 - -var PastClick = function(time, pos, button) { - this.time = time - this.pos = pos - this.button = button -}; - -PastClick.prototype.compare = function (time, pos, button) { - return this.time + DOUBLECLICK_DELAY > time && - cmp(pos, this.pos) == 0 && button == this.button -}; - -var lastClick; -var lastDoubleClick; -function clickRepeat(pos, button) { - var now = +new Date - if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) { - lastClick = lastDoubleClick = null - return "triple" - } else if (lastClick && lastClick.compare(now, pos, button)) { - lastDoubleClick = new PastClick(now, pos, button) - lastClick = null - return "double" - } else { - lastClick = new PastClick(now, pos, button) - lastDoubleClick = null - return "single" - } -} - -// A mouse down can be a single click, double click, triple click, -// start of selection drag, start of text drag, new cursor -// (ctrl-click), rectangle drag (alt-drag), or xwin -// middle-click-paste. Or it might be a click on something we should -// not interfere with, such as a scrollbar or widget. -function onMouseDown(e) { - var cm = this, display = cm.display - if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return } - display.input.ensurePolled() - display.shift = e.shiftKey - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false - setTimeout(function () { return display.scroller.draggable = true; }, 100) - } - return - } - if (clickInGutter(cm, e)) { return } - var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single" - window.focus() - - // #3261: make sure, that we're not starting a second selection - if (button == 1 && cm.state.selectingText) - { cm.state.selectingText(e) } - - if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return } - - if (button == 1) { - if (pos) { leftButtonDown(cm, pos, repeat, e) } - else if (e_target(e) == display.scroller) { e_preventDefault(e) } - } else if (button == 2) { - if (pos) { extendSelection(cm.doc, pos) } - setTimeout(function () { return display.input.focus(); }, 20) - } else if (button == 3) { - if (captureRightClick) { onContextMenu(cm, e) } - else { delayBlurEvent(cm) } - } -} - -function handleMappedButton(cm, button, pos, repeat, event) { - var name = "Click" - if (repeat == "double") { name = "Double" + name } - else if (repeat == "triple") { name = "Triple" + name } - name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name - - return dispatchKey(cm, addModifierNames(name, event), event, function (bound) { - if (typeof bound == "string") { bound = commands[bound] } - if (!bound) { return false } - var done = false - try { - if (cm.isReadOnly()) { cm.state.suppressEdits = true } - done = bound(cm, pos) != Pass - } finally { - cm.state.suppressEdits = false - } - return done - }) -} - -function configureMouse(cm, repeat, event) { - var option = cm.getOption("configureMouse") - var value = option ? option(cm, repeat, event) : {} - if (value.unit == null) { - var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey - value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line" - } - if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey } - if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey } - if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey) } - return value -} - -function leftButtonDown(cm, pos, repeat, event) { - if (ie) { setTimeout(bind(ensureFocus, cm), 0) } - else { cm.curOp.focus = activeElt() } - - var behavior = configureMouse(cm, repeat, event) - - var sel = cm.doc.sel, contained - if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && - repeat == "single" && (contained = sel.contains(pos)) > -1 && - (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) && - (cmp(contained.to(), pos) > 0 || pos.xRel < 0)) - { leftButtonStartDrag(cm, event, pos, behavior) } - else - { leftButtonSelect(cm, event, pos, behavior) } -} - -// Start a text drag. When it ends, see if any dragging actually -// happen, and treat as a click if it didn't. -function leftButtonStartDrag(cm, event, pos, behavior) { - var display = cm.display, moved = false - var dragEnd = operation(cm, function (e) { - if (webkit) { display.scroller.draggable = false } - cm.state.draggingText = false - off(document, "mouseup", dragEnd) - off(document, "mousemove", mouseMove) - off(display.scroller, "dragstart", dragStart) - off(display.scroller, "drop", dragEnd) - if (!moved) { - e_preventDefault(e) - if (!behavior.addNew) - { extendSelection(cm.doc, pos, null, null, behavior.extend) } - // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) - if (webkit || ie && ie_version == 9) - { setTimeout(function () {document.body.focus(); display.input.focus()}, 20) } - else - { display.input.focus() } - } - }) - var mouseMove = function(e2) { - moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10 - } - var dragStart = function () { return moved = true; } - // Let the drag handler handle this. - if (webkit) { display.scroller.draggable = true } - cm.state.draggingText = dragEnd - dragEnd.copy = !behavior.moveOnDrag - // IE's approach to draggable - if (display.scroller.dragDrop) { display.scroller.dragDrop() } - on(document, "mouseup", dragEnd) - on(document, "mousemove", mouseMove) - on(display.scroller, "dragstart", dragStart) - on(display.scroller, "drop", dragEnd) - - delayBlurEvent(cm) - setTimeout(function () { return display.input.focus(); }, 20) -} - -function rangeForUnit(cm, pos, unit) { - if (unit == "char") { return new Range(pos, pos) } - if (unit == "word") { return cm.findWordAt(pos) } - if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } - var result = unit(cm, pos) - return new Range(result.from, result.to) -} - -// Normal selection, as opposed to text dragging. -function leftButtonSelect(cm, event, start, behavior) { - var display = cm.display, doc = cm.doc - e_preventDefault(event) - - var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges - if (behavior.addNew && !behavior.extend) { - ourIndex = doc.sel.contains(start) - if (ourIndex > -1) - { ourRange = ranges[ourIndex] } - else - { ourRange = new Range(start, start) } - } else { - ourRange = doc.sel.primary() - ourIndex = doc.sel.primIndex - } - - if (behavior.unit == "rectangle") { - if (!behavior.addNew) { ourRange = new Range(start, start) } - start = posFromMouse(cm, event, true, true) - ourIndex = -1 - } else { - var range = rangeForUnit(cm, start, behavior.unit) - if (behavior.extend) - { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend) } - else - { ourRange = range } - } - - if (!behavior.addNew) { - ourIndex = 0 - setSelection(doc, new Selection([ourRange], 0), sel_mouse) - startSel = doc.sel - } else if (ourIndex == -1) { - ourIndex = ranges.length - setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), - {scroll: false, origin: "*mouse"}) - } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { - setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), - {scroll: false, origin: "*mouse"}) - startSel = doc.sel - } else { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse) - } - - var lastPos = start - function extendTo(pos) { - if (cmp(lastPos, pos) == 0) { return } - lastPos = pos - - if (behavior.unit == "rectangle") { - var ranges = [], tabSize = cm.options.tabSize - var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize) - var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize) - var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol) - for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); - line <= end; line++) { - var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize) - if (left == right) - { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))) } - else if (text.length > leftPos) - { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))) } - } - if (!ranges.length) { ranges.push(new Range(start, start)) } - setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), - {origin: "*mouse", scroll: false}) - cm.scrollIntoView(pos) - } else { - var oldRange = ourRange - var range = rangeForUnit(cm, pos, behavior.unit) - var anchor = oldRange.anchor, head - if (cmp(range.anchor, anchor) > 0) { - head = range.head - anchor = minPos(oldRange.from(), range.anchor) - } else { - head = range.anchor - anchor = maxPos(oldRange.to(), range.head) - } - var ranges$1 = startSel.ranges.slice(0) - ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head) - setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse) - } - } - - var editorSize = display.wrapper.getBoundingClientRect() - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0 - - function extend(e) { - var curCount = ++counter - var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle") - if (!cur) { return } - if (cmp(cur, lastPos) != 0) { - cm.curOp.focus = activeElt() - extendTo(cur) - var visible = visibleLines(display, doc) - if (cur.line >= visible.to || cur.line < visible.from) - { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e) }}), 150) } - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0 - if (outside) { setTimeout(operation(cm, function () { - if (counter != curCount) { return } - display.scroller.scrollTop += outside - extend(e) - }), 50) } - } - } - - function done(e) { - cm.state.selectingText = false - counter = Infinity - e_preventDefault(e) - display.input.focus() - off(document, "mousemove", move) - off(document, "mouseup", up) - doc.history.lastSelOrigin = null - } - - var move = operation(cm, function (e) { - if (!e_button(e)) { done(e) } - else { extend(e) } - }) - var up = operation(cm, done) - cm.state.selectingText = up - on(document, "mousemove", move) - on(document, "mouseup", up) -} - - -// Determines whether an event happened in the gutter, and fires the -// handlers for the corresponding event. -function gutterEvent(cm, e, type, prevent) { - var mX, mY - try { mX = e.clientX; mY = e.clientY } - catch(e) { return false } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false } - if (prevent) { e_preventDefault(e) } - - var display = cm.display - var lineBox = display.lineDiv.getBoundingClientRect() - - if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) } - mY -= lineBox.top - display.viewOffset - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i] - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY) - var gutter = cm.options.gutters[i] - signal(cm, type, cm, line, gutter, e) - return e_defaultPrevented(e) - } - } -} - -function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true) -} - -// CONTEXT MENU HANDLING - -// To make the context menu work, we need to briefly unhide the -// textarea (making it as unobtrusive as possible) to let the -// right-click take effect on it. -function onContextMenu(cm, e) { - if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return } - if (signalDOMEvent(cm, e, "contextmenu")) { return } - cm.display.input.onContextMenu(e) -} - -function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) { return false } - return gutterEvent(cm, e, "gutterContextMenu", false) -} - -function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-") - clearCaches(cm) -} - -var Init = {toString: function(){return "CodeMirror.Init"}} - -var defaults = {} -var optionHandlers = {} - -function defineOptions(CodeMirror) { - var optionHandlers = CodeMirror.optionHandlers - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt - if (handle) { optionHandlers[name] = - notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old) }} : handle } - } - - CodeMirror.defineOption = option - - // Passed to option handlers when there is no old value. - CodeMirror.Init = Init - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function (cm, val) { return cm.setValue(val); }, true) - option("mode", null, function (cm, val) { - cm.doc.modeOption = val - loadMode(cm) - }, true) - - option("indentUnit", 2, loadMode, true) - option("indentWithTabs", false) - option("smartIndent", true) - option("tabSize", 4, function (cm) { - resetModeState(cm) - clearCaches(cm) - regChange(cm) - }, true) - option("lineSeparator", null, function (cm, val) { - cm.doc.lineSep = val - if (!val) { return } - var newBreaks = [], lineNo = cm.doc.first - cm.doc.iter(function (line) { - for (var pos = 0;;) { - var found = line.text.indexOf(val, pos) - if (found == -1) { break } - pos = found + val.length - newBreaks.push(Pos(lineNo, found)) - } - lineNo++ - }) - for (var i = newBreaks.length - 1; i >= 0; i--) - { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) } - }) - option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) { - cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g") - if (old != Init) { cm.refresh() } - }) - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true) - option("electricChars", true) - option("inputStyle", mobile ? "contenteditable" : "textarea", function () { - throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME - }, true) - option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true) - option("rtlMoveVisually", !windows) - option("wholeLineUpdateBefore", true) - - option("theme", "default", function (cm) { - themeChanged(cm) - guttersChanged(cm) - }, true) - option("keyMap", "default", function (cm, val, old) { - var next = getKeyMap(val) - var prev = old != Init && getKeyMap(old) - if (prev && prev.detach) { prev.detach(cm, next) } - if (next.attach) { next.attach(cm, prev || null) } - }) - option("extraKeys", null) - option("configureMouse", null) - - option("lineWrapping", false, wrappingChanged, true) - option("gutters", [], function (cm) { - setGuttersForLineNumbers(cm.options) - guttersChanged(cm) - }, true) - option("fixedGutter", true, function (cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0" - cm.refresh() - }, true) - option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true) - option("scrollbarStyle", "native", function (cm) { - initScrollbars(cm) - updateScrollbars(cm) - cm.display.scrollbars.setScrollTop(cm.doc.scrollTop) - cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft) - }, true) - option("lineNumbers", false, function (cm) { - setGuttersForLineNumbers(cm.options) - guttersChanged(cm) - }, true) - option("firstLineNumber", 1, guttersChanged, true) - option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true) - option("showCursorWhenSelecting", false, updateSelection, true) - - option("resetSelectionOnContextMenu", true) - option("lineWiseCopyCut", true) - option("pasteLinesPerSelection", true) - - option("readOnly", false, function (cm, val) { - if (val == "nocursor") { - onBlur(cm) - cm.display.input.blur() - } - cm.display.input.readOnlyChanged(val) - }) - option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset() }}, true) - option("dragDrop", true, dragDropChanged) - option("allowDropFileTypes", null) - - option("cursorBlinkRate", 530) - option("cursorScrollMargin", 0) - option("cursorHeight", 1, updateSelection, true) - option("singleCursorHeightPerLine", true, updateSelection, true) - option("workTime", 100) - option("workDelay", 100) - option("flattenSpans", true, resetModeState, true) - option("addModeClass", false, resetModeState, true) - option("pollInterval", 100) - option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; }) - option("historyEventDelay", 1250) - option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true) - option("maxHighlightLength", 10000, resetModeState, true) - option("moveInputWithCursor", true, function (cm, val) { - if (!val) { cm.display.input.resetPosition() } - }) - - option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; }) - option("autofocus", null) - option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true) -} - -function guttersChanged(cm) { - updateGutters(cm) - regChange(cm) - alignHorizontally(cm) -} - -function dragDropChanged(cm, value, old) { - var wasOn = old && old != Init - if (!value != !wasOn) { - var funcs = cm.display.dragFunctions - var toggle = value ? on : off - toggle(cm.display.scroller, "dragstart", funcs.start) - toggle(cm.display.scroller, "dragenter", funcs.enter) - toggle(cm.display.scroller, "dragover", funcs.over) - toggle(cm.display.scroller, "dragleave", funcs.leave) - toggle(cm.display.scroller, "drop", funcs.drop) - } -} - -function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - addClass(cm.display.wrapper, "CodeMirror-wrap") - cm.display.sizer.style.minWidth = "" - cm.display.sizerWidth = null - } else { - rmClass(cm.display.wrapper, "CodeMirror-wrap") - findMaxLine(cm) - } - estimateLineHeights(cm) - regChange(cm) - clearCaches(cm) - setTimeout(function () { return updateScrollbars(cm); }, 100) -} - -// A CodeMirror instance represents an editor. This is the object -// that user code is usually dealing with. - -function CodeMirror(place, options) { - var this$1 = this; - - if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) } - - this.options = options = options ? copyObj(options) : {} - // Determine effective options based on given values and defaults. - copyObj(defaults, options, false) - setGuttersForLineNumbers(options) - - var doc = options.value - if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) } - this.doc = doc - - var input = new CodeMirror.inputStyles[options.inputStyle](this) - var display = this.display = new Display(place, doc, input) - display.wrapper.CodeMirror = this - updateGutters(this) - themeChanged(this) - if (options.lineWrapping) - { this.display.wrapper.className += " CodeMirror-wrap" } - initScrollbars(this) - - this.state = { - keyMaps: [], // stores maps added by addKeyMap - overlays: [], // highlighting overlays, as added by addOverlay - modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info - overwrite: false, - delayingBlurEvent: false, - focused: false, - suppressEdits: false, // used to disable editing during key handlers when in readOnly mode - pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll - selectingText: false, - draggingText: false, - highlight: new Delayed(), // stores highlight worker timeout - keySeq: null, // Unfinished key sequence - specialChars: null - } - - if (options.autofocus && !mobile) { display.input.focus() } - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20) } - - registerEventHandlers(this) - ensureGlobalHandlers() - - startOperation(this) - this.curOp.forceUpdate = true - attachDoc(this, doc) - - if ((options.autofocus && !mobile) || this.hasFocus()) - { setTimeout(bind(onFocus, this), 20) } - else - { onBlur(this) } - - for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt)) - { optionHandlers[opt](this$1, options[opt], Init) } } - maybeUpdateLineNumberWidth(this) - if (options.finishInit) { options.finishInit(this) } - for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1) } - endOperation(this) - // Suppress optimizelegibility in Webkit, since it breaks text - // measuring on line wrapping boundaries. - if (webkit && options.lineWrapping && - getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") - { display.lineDiv.style.textRendering = "auto" } -} - -// The default configuration options. -CodeMirror.defaults = defaults -// Functions to run when options are changed. -CodeMirror.optionHandlers = optionHandlers - -// Attach the necessary event handlers when initializing the editor -function registerEventHandlers(cm) { - var d = cm.display - on(d.scroller, "mousedown", operation(cm, onMouseDown)) - // Older IE's will not fire a second mousedown for a double click - if (ie && ie_version < 11) - { on(d.scroller, "dblclick", operation(cm, function (e) { - if (signalDOMEvent(cm, e)) { return } - var pos = posFromMouse(cm, e) - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return } - e_preventDefault(e) - var word = cm.findWordAt(pos) - extendSelection(cm.doc, word.anchor, word.head) - })) } - else - { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }) } - // Some browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for these browsers. - if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }) } - - // Used to suppress mouse event handling when a touch happens - var touchFinished, prevTouch = {end: 0} - function finishTouch() { - if (d.activeTouch) { - touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000) - prevTouch = d.activeTouch - prevTouch.end = +new Date - } - } - function isMouseLikeTouchEvent(e) { - if (e.touches.length != 1) { return false } - var touch = e.touches[0] - return touch.radiusX <= 1 && touch.radiusY <= 1 - } - function farAway(touch, other) { - if (other.left == null) { return true } - var dx = other.left - touch.left, dy = other.top - touch.top - return dx * dx + dy * dy > 20 * 20 - } - on(d.scroller, "touchstart", function (e) { - if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { - d.input.ensurePolled() - clearTimeout(touchFinished) - var now = +new Date - d.activeTouch = {start: now, moved: false, - prev: now - prevTouch.end <= 300 ? prevTouch : null} - if (e.touches.length == 1) { - d.activeTouch.left = e.touches[0].pageX - d.activeTouch.top = e.touches[0].pageY - } - } - }) - on(d.scroller, "touchmove", function () { - if (d.activeTouch) { d.activeTouch.moved = true } - }) - on(d.scroller, "touchend", function (e) { - var touch = d.activeTouch - if (touch && !eventInWidget(d, e) && touch.left != null && - !touch.moved && new Date - touch.start < 300) { - var pos = cm.coordsChar(d.activeTouch, "page"), range - if (!touch.prev || farAway(touch, touch.prev)) // Single tap - { range = new Range(pos, pos) } - else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap - { range = cm.findWordAt(pos) } - else // Triple tap - { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } - cm.setSelection(range.anchor, range.head) - cm.focus() - e_preventDefault(e) - } - finishTouch() - }) - on(d.scroller, "touchcancel", finishTouch) - - // Sync scrolling between fake scrollbars and real scrollable - // area, ensure viewport is updated when scrolling. - on(d.scroller, "scroll", function () { - if (d.scroller.clientHeight) { - updateScrollTop(cm, d.scroller.scrollTop) - setScrollLeft(cm, d.scroller.scrollLeft, true) - signal(cm, "scroll", cm) - } - }) - - // Listen to wheel events in order to try and update the viewport on time. - on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); }) - on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); }) - - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }) - - d.dragFunctions = { - enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e) }}, - over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e) }}, - start: function (e) { return onDragStart(cm, e); }, - drop: operation(cm, onDrop), - leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm) }} - } - - var inp = d.input.getField() - on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); }) - on(inp, "keydown", operation(cm, onKeyDown)) - on(inp, "keypress", operation(cm, onKeyPress)) - on(inp, "focus", function (e) { return onFocus(cm, e); }) - on(inp, "blur", function (e) { return onBlur(cm, e); }) -} - -var initHooks = [] -CodeMirror.defineInitHook = function (f) { return initHooks.push(f); } - -// Indent the given line. The how parameter can be "smart", -// "add"/null, "subtract", or "prev". When aggressive is false -// (typically set to true for forced single-line indents), empty -// lines are not indented, and places where the mode returns Pass -// are left alone. -function indentLine(cm, n, how, aggressive) { - var doc = cm.doc, state - if (how == null) { how = "add" } - if (how == "smart") { - // Fall back to "prev" when the mode doesn't have an indentation - // method. - if (!doc.mode.indent) { how = "prev" } - else { state = getContextBefore(cm, n).state } - } - - var tabSize = cm.options.tabSize - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize) - if (line.stateAfter) { line.stateAfter = null } - var curSpaceString = line.text.match(/^\s*/)[0], indentation - if (!aggressive && !/\S/.test(line.text)) { - indentation = 0 - how = "not" - } else if (how == "smart") { - indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text) - if (indentation == Pass || indentation > 150) { - if (!aggressive) { return } - how = "prev" - } - } - if (how == "prev") { - if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize) } - else { indentation = 0 } - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit - } else if (typeof how == "number") { - indentation = curSpace + how - } - indentation = Math.max(0, indentation) - - var indentString = "", pos = 0 - if (cm.options.indentWithTabs) - { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t"} } - if (pos < indentation) { indentString += spaceStr(indentation - pos) } - - if (indentString != curSpaceString) { - replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input") - line.stateAfter = null - return true - } else { - // Ensure that, if the cursor was in the whitespace at the start - // of the line, it is moved to the end of that space. - for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) { - var range = doc.sel.ranges[i$1] - if (range.head.line == n && range.head.ch < curSpaceString.length) { - var pos$1 = Pos(n, curSpaceString.length) - replaceOneSelection(doc, i$1, new Range(pos$1, pos$1)) - break - } - } - } -} - -// This will be set to a {lineWise: bool, text: [string]} object, so -// that, when pasting, we know what kind of selections the copied -// text was made out of. -var lastCopied = null - -function setLastCopied(newLastCopied) { - lastCopied = newLastCopied -} - -function applyTextInput(cm, inserted, deleted, sel, origin) { - var doc = cm.doc - cm.display.shift = false - if (!sel) { sel = doc.sel } - - var paste = cm.state.pasteIncoming || origin == "paste" - var textLines = splitLinesAuto(inserted), multiPaste = null - // When pasing N lines into N selections, insert one line per selection - if (paste && sel.ranges.length > 1) { - if (lastCopied && lastCopied.text.join("\n") == inserted) { - if (sel.ranges.length % lastCopied.text.length == 0) { - multiPaste = [] - for (var i = 0; i < lastCopied.text.length; i++) - { multiPaste.push(doc.splitLines(lastCopied.text[i])) } - } - } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) { - multiPaste = map(textLines, function (l) { return [l]; }) - } - } - - var updateInput - // Normal behavior is to insert the new text into every selection - for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) { - var range = sel.ranges[i$1] - var from = range.from(), to = range.to() - if (range.empty()) { - if (deleted && deleted > 0) // Handle deletion - { from = Pos(from.line, from.ch - deleted) } - else if (cm.state.overwrite && !paste) // Handle overwrite - { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) } - else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted) - { from = to = Pos(from.line, 0) } - } - updateInput = cm.curOp.updateInput - var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines, - origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")} - makeChange(cm.doc, changeEvent) - signalLater(cm, "inputRead", cm, changeEvent) - } - if (inserted && !paste) - { triggerElectric(cm, inserted) } - - ensureCursorVisible(cm) - cm.curOp.updateInput = updateInput - cm.curOp.typing = true - cm.state.pasteIncoming = cm.state.cutIncoming = false -} - -function handlePaste(e, cm) { - var pasted = e.clipboardData && e.clipboardData.getData("Text") - if (pasted) { - e.preventDefault() - if (!cm.isReadOnly() && !cm.options.disableInput) - { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }) } - return true - } -} - -function triggerElectric(cm, inserted) { - // When an 'electric' character is inserted, immediately trigger a reindent - if (!cm.options.electricChars || !cm.options.smartIndent) { return } - var sel = cm.doc.sel - - for (var i = sel.ranges.length - 1; i >= 0; i--) { - var range = sel.ranges[i] - if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue } - var mode = cm.getModeAt(range.head) - var indented = false - if (mode.electricChars) { - for (var j = 0; j < mode.electricChars.length; j++) - { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indented = indentLine(cm, range.head.line, "smart") - break - } } - } else if (mode.electricInput) { - if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) - { indented = indentLine(cm, range.head.line, "smart") } - } - if (indented) { signalLater(cm, "electricInput", cm, range.head.line) } - } -} - -function copyableRanges(cm) { - var text = [], ranges = [] - for (var i = 0; i < cm.doc.sel.ranges.length; i++) { - var line = cm.doc.sel.ranges[i].head.line - var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)} - ranges.push(lineRange) - text.push(cm.getRange(lineRange.anchor, lineRange.head)) - } - return {text: text, ranges: ranges} -} - -function disableBrowserMagic(field, spellcheck) { - field.setAttribute("autocorrect", "off") - field.setAttribute("autocapitalize", "off") - field.setAttribute("spellcheck", !!spellcheck) -} - -function hiddenTextarea() { - var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none") - var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;") - // The textarea is kept positioned near the cursor to prevent the - // fact that it'll be scrolled into view on input from scrolling - // our fake cursor out of view. On webkit, when wrap=off, paste is - // very slow. So make the area wide instead. - if (webkit) { te.style.width = "1000px" } - else { te.setAttribute("wrap", "off") } - // If border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) { te.style.border = "1px solid black" } - disableBrowserMagic(te) - return div -} - -// The publicly visible API. Note that methodOp(f) means -// 'wrap f in an operation, performed on its `this` parameter'. - -// This is not the complete set of editor methods. Most of the -// methods defined on the Doc type are also injected into -// CodeMirror.prototype, for backwards compatibility and -// convenience. - -function addEditorMethods(CodeMirror) { - var optionHandlers = CodeMirror.optionHandlers - - var helpers = CodeMirror.helpers = {} - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function(){window.focus(); this.display.input.focus()}, - - setOption: function(option, value) { - var options = this.options, old = options[option] - if (options[option] == value && option != "mode") { return } - options[option] = value - if (optionHandlers.hasOwnProperty(option)) - { operation(this, optionHandlers[option])(this, value, old) } - signal(this, "optionChange", this, option) - }, - - getOption: function(option) {return this.options[option]}, - getDoc: function() {return this.doc}, - - addKeyMap: function(map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)) - }, - removeKeyMap: function(map) { - var maps = this.state.keyMaps - for (var i = 0; i < maps.length; ++i) - { if (maps[i] == map || maps[i].name == map) { - maps.splice(i, 1) - return true - } } - }, - - addOverlay: methodOp(function(spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec) - if (mode.startState) { throw new Error("Overlays may not be stateful.") } - insertSorted(this.state.overlays, - {mode: mode, modeSpec: spec, opaque: options && options.opaque, - priority: (options && options.priority) || 0}, - function (overlay) { return overlay.priority; }) - this.state.modeGen++ - regChange(this) - }), - removeOverlay: methodOp(function(spec) { - var this$1 = this; - - var overlays = this.state.overlays - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1) - this$1.state.modeGen++ - regChange(this$1) - return - } - } - }), - - indentLine: methodOp(function(n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev" } - else { dir = dir ? "add" : "subtract" } - } - if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive) } - }), - indentSelection: methodOp(function(how) { - var this$1 = this; - - var ranges = this.doc.sel.ranges, end = -1 - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i] - if (!range.empty()) { - var from = range.from(), to = range.to() - var start = Math.max(end, from.line) - end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1 - for (var j = start; j < end; ++j) - { indentLine(this$1, j, how) } - var newRanges = this$1.doc.sel.ranges - if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) - { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll) } - } else if (range.head.line > end) { - indentLine(this$1, range.head.line, how, true) - end = range.head.line - if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1) } - } - } - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function(pos, precise) { - return takeToken(this, pos, precise) - }, - - getLineTokens: function(line, precise) { - return takeToken(this, Pos(line), precise, true) - }, - - getTokenTypeAt: function(pos) { - pos = clipPos(this.doc, pos) - var styles = getLineStyles(this, getLine(this.doc, pos.line)) - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch - var type - if (ch == 0) { type = styles[2] } - else { for (;;) { - var mid = (before + after) >> 1 - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid } - else if (styles[mid * 2 + 1] < ch) { before = mid + 1 } - else { type = styles[mid * 2 + 2]; break } - } } - var cut = type ? type.indexOf("overlay ") : -1 - return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1) - }, - - getModeAt: function(pos) { - var mode = this.doc.mode - if (!mode.innerMode) { return mode } - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode - }, - - getHelper: function(pos, type) { - return this.getHelpers(pos, type)[0] - }, - - getHelpers: function(pos, type) { - var this$1 = this; - - var found = [] - if (!helpers.hasOwnProperty(type)) { return found } - var help = helpers[type], mode = this.getModeAt(pos) - if (typeof mode[type] == "string") { - if (help[mode[type]]) { found.push(help[mode[type]]) } - } else if (mode[type]) { - for (var i = 0; i < mode[type].length; i++) { - var val = help[mode[type][i]] - if (val) { found.push(val) } - } - } else if (mode.helperType && help[mode.helperType]) { - found.push(help[mode.helperType]) - } else if (help[mode.name]) { - found.push(help[mode.name]) - } - for (var i$1 = 0; i$1 < help._global.length; i$1++) { - var cur = help._global[i$1] - if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1) - { found.push(cur.val) } - } - return found - }, - - getStateAfter: function(line, precise) { - var doc = this.doc - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line) - return getContextBefore(this, line + 1, precise).state - }, - - cursorCoords: function(start, mode) { - var pos, range = this.doc.sel.primary() - if (start == null) { pos = range.head } - else if (typeof start == "object") { pos = clipPos(this.doc, start) } - else { pos = start ? range.from() : range.to() } - return cursorCoords(this, pos, mode || "page") - }, - - charCoords: function(pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page") - }, - - coordsChar: function(coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page") - return coordsChar(this, coords.left, coords.top) - }, - - lineAtHeight: function(height, mode) { - height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top - return lineAtHeight(this.doc, height + this.display.viewOffset) - }, - heightAtLine: function(line, mode, includeWidgets) { - var end = false, lineObj - if (typeof line == "number") { - var last = this.doc.first + this.doc.size - 1 - if (line < this.doc.first) { line = this.doc.first } - else if (line > last) { line = last; end = true } - lineObj = getLine(this.doc, line) - } else { - lineObj = line - } - return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top + - (end ? this.doc.height - heightAtLine(lineObj) : 0) - }, - - defaultTextHeight: function() { return textHeight(this.display) }, - defaultCharWidth: function() { return charWidth(this.display) }, - - getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}}, - - addWidget: function(pos, node, scroll, vert, horiz) { - var display = this.display - pos = cursorCoords(this, clipPos(this.doc, pos)) - var top = pos.bottom, left = pos.left - node.style.position = "absolute" - node.setAttribute("cm-ignore-events", "true") - this.display.input.setUneditable(node) - display.sizer.appendChild(node) - if (vert == "over") { - top = pos.top - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth) - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - { top = pos.top - node.offsetHeight } - else if (pos.bottom + node.offsetHeight <= vspace) - { top = pos.bottom } - if (left + node.offsetWidth > hspace) - { left = hspace - node.offsetWidth } - } - node.style.top = top + "px" - node.style.left = node.style.right = "" - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth - node.style.right = "0px" - } else { - if (horiz == "left") { left = 0 } - else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2 } - node.style.left = left + "px" - } - if (scroll) - { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}) } - }, - - triggerOnKeyDown: methodOp(onKeyDown), - triggerOnKeyPress: methodOp(onKeyPress), - triggerOnKeyUp: onKeyUp, - triggerOnMouseDown: methodOp(onMouseDown), - - execCommand: function(cmd) { - if (commands.hasOwnProperty(cmd)) - { return commands[cmd].call(null, this) } - }, - - triggerElectric: methodOp(function(text) { triggerElectric(this, text) }), - - findPosH: function(from, amount, unit, visually) { - var this$1 = this; - - var dir = 1 - if (amount < 0) { dir = -1; amount = -amount } - var cur = clipPos(this.doc, from) - for (var i = 0; i < amount; ++i) { - cur = findPosH(this$1.doc, cur, dir, unit, visually) - if (cur.hitSide) { break } - } - return cur - }, - - moveH: methodOp(function(dir, unit) { - var this$1 = this; - - this.extendSelectionsBy(function (range) { - if (this$1.display.shift || this$1.doc.extend || range.empty()) - { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) } - else - { return dir < 0 ? range.from() : range.to() } - }, sel_move) - }), - - deleteH: methodOp(function(dir, unit) { - var sel = this.doc.sel, doc = this.doc - if (sel.somethingSelected()) - { doc.replaceSelection("", null, "+delete") } - else - { deleteNearSelection(this, function (range) { - var other = findPosH(doc, range.head, dir, unit, false) - return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other} - }) } - }), - - findPosV: function(from, amount, unit, goalColumn) { - var this$1 = this; - - var dir = 1, x = goalColumn - if (amount < 0) { dir = -1; amount = -amount } - var cur = clipPos(this.doc, from) - for (var i = 0; i < amount; ++i) { - var coords = cursorCoords(this$1, cur, "div") - if (x == null) { x = coords.left } - else { coords.left = x } - cur = findPosV(this$1, coords, dir, unit) - if (cur.hitSide) { break } - } - return cur - }, - - moveV: methodOp(function(dir, unit) { - var this$1 = this; - - var doc = this.doc, goals = [] - var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected() - doc.extendSelectionsBy(function (range) { - if (collapse) - { return dir < 0 ? range.from() : range.to() } - var headPos = cursorCoords(this$1, range.head, "div") - if (range.goalColumn != null) { headPos.left = range.goalColumn } - goals.push(headPos.left) - var pos = findPosV(this$1, headPos, dir, unit) - if (unit == "page" && range == doc.sel.primary()) - { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top) } - return pos - }, sel_move) - if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++) - { doc.sel.ranges[i].goalColumn = goals[i] } } - }), - - // Find the word at the given position (as returned by coordsChar). - findWordAt: function(pos) { - var doc = this.doc, line = getLine(doc, pos.line).text - var start = pos.ch, end = pos.ch - if (line) { - var helper = this.getHelper(pos, "wordChars") - if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end } - var startChar = line.charAt(start) - var check = isWordChar(startChar, helper) - ? function (ch) { return isWordChar(ch, helper); } - : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); } - : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); } - while (start > 0 && check(line.charAt(start - 1))) { --start } - while (end < line.length && check(line.charAt(end))) { ++end } - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)) - }, - - toggleOverwrite: function(value) { - if (value != null && value == this.state.overwrite) { return } - if (this.state.overwrite = !this.state.overwrite) - { addClass(this.display.cursorDiv, "CodeMirror-overwrite") } - else - { rmClass(this.display.cursorDiv, "CodeMirror-overwrite") } - - signal(this, "overwriteToggle", this, this.state.overwrite) - }, - hasFocus: function() { return this.display.input.getField() == activeElt() }, - isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) }, - - scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }), - getScrollInfo: function() { - var scroller = this.display.scroller - return {left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, - width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, - clientHeight: displayHeight(this), clientWidth: displayWidth(this)} - }, - - scrollIntoView: methodOp(function(range, margin) { - if (range == null) { - range = {from: this.doc.sel.primary().head, to: null} - if (margin == null) { margin = this.options.cursorScrollMargin } - } else if (typeof range == "number") { - range = {from: Pos(range, 0), to: null} - } else if (range.from == null) { - range = {from: range, to: null} - } - if (!range.to) { range.to = range.from } - range.margin = margin || 0 - - if (range.from.line != null) { - scrollToRange(this, range) - } else { - scrollToCoordsRange(this, range.from, range.to, range.margin) - } - }), - - setSize: methodOp(function(width, height) { - var this$1 = this; - - var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; } - if (width != null) { this.display.wrapper.style.width = interpret(width) } - if (height != null) { this.display.wrapper.style.height = interpret(height) } - if (this.options.lineWrapping) { clearLineMeasurementCache(this) } - var lineNo = this.display.viewFrom - this.doc.iter(lineNo, this.display.viewTo, function (line) { - if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) - { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, "widget"); break } } } - ++lineNo - }) - this.curOp.forceUpdate = true - signal(this, "refresh", this) - }), - - operation: function(f){return runInOp(this, f)}, - startOperation: function(){return startOperation(this)}, - endOperation: function(){return endOperation(this)}, - - refresh: methodOp(function() { - var oldHeight = this.display.cachedTextHeight - regChange(this) - this.curOp.forceUpdate = true - clearCaches(this) - scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop) - updateGutterSpace(this) - if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) - { estimateLineHeights(this) } - signal(this, "refresh", this) - }), - - swapDoc: methodOp(function(doc) { - var old = this.doc - old.cm = null - attachDoc(this, doc) - clearCaches(this) - this.display.input.reset() - scrollToCoords(this, doc.scrollLeft, doc.scrollTop) - this.curOp.forceScroll = true - signalLater(this, "swapDoc", this, old) - return old - }), - - getInputField: function(){return this.display.input.getField()}, - getWrapperElement: function(){return this.display.wrapper}, - getScrollerElement: function(){return this.display.scroller}, - getGutterElement: function(){return this.display.gutters} - } - eventMixin(CodeMirror) - - CodeMirror.registerHelper = function(type, name, value) { - if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []} } - helpers[type][name] = value - } - CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { - CodeMirror.registerHelper(type, name, value) - helpers[type]._global.push({pred: predicate, val: value}) - } -} - -// Used for horizontal relative motion. Dir is -1 or 1 (left or -// right), unit can be "char", "column" (like char, but doesn't -// cross line boundaries), "word" (across next word), or "group" (to -// the start of next group of word or non-word-non-whitespace -// chars). The visually param controls whether, in right-to-left -// text, direction 1 means to move towards the next index in the -// string, or towards the character to the right of the current -// position. The resulting position will have a hitSide=true -// property if it reached the end of the document. -function findPosH(doc, pos, dir, unit, visually) { - var oldPos = pos - var origDir = dir - var lineObj = getLine(doc, pos.line) - function findNextLine() { - var l = pos.line + dir - if (l < doc.first || l >= doc.first + doc.size) { return false } - pos = new Pos(l, pos.ch, pos.sticky) - return lineObj = getLine(doc, l) - } - function moveOnce(boundToLine) { - var next - if (visually) { - next = moveVisually(doc.cm, lineObj, pos, dir) - } else { - next = moveLogically(lineObj, pos, dir) - } - if (next == null) { - if (!boundToLine && findNextLine()) - { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir) } - else - { return false } - } else { - pos = next - } - return true - } - - if (unit == "char") { - moveOnce() - } else if (unit == "column") { - moveOnce(true) - } else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group" - var helper = doc.cm && doc.cm.getHelper(pos, "wordChars") - for (var first = true;; first = false) { - if (dir < 0 && !moveOnce(!first)) { break } - var cur = lineObj.text.charAt(pos.ch) || "\n" - var type = isWordChar(cur, helper) ? "w" - : group && cur == "\n" ? "n" - : !group || /\s/.test(cur) ? null - : "p" - if (group && !first && !type) { type = "s" } - if (sawType && sawType != type) { - if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after"} - break - } - - if (type) { sawType = type } - if (dir > 0 && !moveOnce(!first)) { break } - } - } - var result = skipAtomic(doc, pos, oldPos, origDir, true) - if (equalCursorPos(oldPos, result)) { result.hitSide = true } - return result -} - -// For relative vertical movement. Dir may be -1 or 1. Unit can be -// "page" or "line". The resulting position will have a hitSide=true -// property if it reached the end of the document. -function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight) - var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3) - y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount - - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3 - } - var target - for (;;) { - target = coordsChar(cm, x, y) - if (!target.outside) { break } - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break } - y += dir * 5 - } - return target -} - -// CONTENTEDITABLE INPUT STYLE - -var ContentEditableInput = function(cm) { - this.cm = cm - this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null - this.polling = new Delayed() - this.composing = null - this.gracePeriod = false - this.readDOMTimeout = null -}; - -ContentEditableInput.prototype.init = function (display) { - var this$1 = this; - - var input = this, cm = input.cm - var div = input.div = display.lineDiv - disableBrowserMagic(div, cm.options.spellcheck) - - on(div, "paste", function (e) { - if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } - // IE doesn't fire input events, so we schedule a read for the pasted content in this way - if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20) } - }) - - on(div, "compositionstart", function (e) { - this$1.composing = {data: e.data, done: false} - }) - on(div, "compositionupdate", function (e) { - if (!this$1.composing) { this$1.composing = {data: e.data, done: false} } - }) - on(div, "compositionend", function (e) { - if (this$1.composing) { - if (e.data != this$1.composing.data) { this$1.readFromDOMSoon() } - this$1.composing.done = true - } - }) - - on(div, "touchstart", function () { return input.forceCompositionEnd(); }) - - on(div, "input", function () { - if (!this$1.composing) { this$1.readFromDOMSoon() } - }) - - function onCopyCut(e) { - if (signalDOMEvent(cm, e)) { return } - if (cm.somethingSelected()) { - setLastCopied({lineWise: false, text: cm.getSelections()}) - if (e.type == "cut") { cm.replaceSelection("", null, "cut") } - } else if (!cm.options.lineWiseCopyCut) { - return - } else { - var ranges = copyableRanges(cm) - setLastCopied({lineWise: true, text: ranges.text}) - if (e.type == "cut") { - cm.operation(function () { - cm.setSelections(ranges.ranges, 0, sel_dontScroll) - cm.replaceSelection("", null, "cut") - }) - } - } - if (e.clipboardData) { - e.clipboardData.clearData() - var content = lastCopied.text.join("\n") - // iOS exposes the clipboard API, but seems to discard content inserted into it - e.clipboardData.setData("Text", content) - if (e.clipboardData.getData("Text") == content) { - e.preventDefault() - return - } - } - // Old-fashioned briefly-focus-a-textarea hack - var kludge = hiddenTextarea(), te = kludge.firstChild - cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild) - te.value = lastCopied.text.join("\n") - var hadFocus = document.activeElement - selectInput(te) - setTimeout(function () { - cm.display.lineSpace.removeChild(kludge) - hadFocus.focus() - if (hadFocus == div) { input.showPrimarySelection() } - }, 50) - } - on(div, "copy", onCopyCut) - on(div, "cut", onCopyCut) -}; - -ContentEditableInput.prototype.prepareSelection = function () { - var result = prepareSelection(this.cm, false) - result.focus = this.cm.state.focused - return result -}; - -ContentEditableInput.prototype.showSelection = function (info, takeFocus) { - if (!info || !this.cm.display.view.length) { return } - if (info.focus || takeFocus) { this.showPrimarySelection() } - this.showMultipleSelections(info) -}; - -ContentEditableInput.prototype.showPrimarySelection = function () { - var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary() - var from = prim.from(), to = prim.to() - - if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { - sel.removeAllRanges() - return - } - - var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) - var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset) - if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && - cmp(minPos(curAnchor, curFocus), from) == 0 && - cmp(maxPos(curAnchor, curFocus), to) == 0) - { return } - - var view = cm.display.view - var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) || - {node: view[0].measure.map[2], offset: 0} - var end = to.line < cm.display.viewTo && posToDOM(cm, to) - if (!end) { - var measure = view[view.length - 1].measure - var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map - end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]} - } - - if (!start || !end) { - sel.removeAllRanges() - return - } - - var old = sel.rangeCount && sel.getRangeAt(0), rng - try { rng = range(start.node, start.offset, end.offset, end.node) } - catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible - if (rng) { - if (!gecko && cm.state.focused) { - sel.collapse(start.node, start.offset) - if (!rng.collapsed) { - sel.removeAllRanges() - sel.addRange(rng) - } - } else { - sel.removeAllRanges() - sel.addRange(rng) - } - if (old && sel.anchorNode == null) { sel.addRange(old) } - else if (gecko) { this.startGracePeriod() } - } - this.rememberSelection() -}; - -ContentEditableInput.prototype.startGracePeriod = function () { - var this$1 = this; - - clearTimeout(this.gracePeriod) - this.gracePeriod = setTimeout(function () { - this$1.gracePeriod = false - if (this$1.selectionChanged()) - { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }) } - }, 20) -}; - -ContentEditableInput.prototype.showMultipleSelections = function (info) { - removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors) - removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection) -}; - -ContentEditableInput.prototype.rememberSelection = function () { - var sel = window.getSelection() - this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset - this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset -}; - -ContentEditableInput.prototype.selectionInEditor = function () { - var sel = window.getSelection() - if (!sel.rangeCount) { return false } - var node = sel.getRangeAt(0).commonAncestorContainer - return contains(this.div, node) -}; - -ContentEditableInput.prototype.focus = function () { - if (this.cm.options.readOnly != "nocursor") { - if (!this.selectionInEditor()) - { this.showSelection(this.prepareSelection(), true) } - this.div.focus() - } -}; -ContentEditableInput.prototype.blur = function () { this.div.blur() }; -ContentEditableInput.prototype.getField = function () { return this.div }; - -ContentEditableInput.prototype.supportsTouch = function () { return true }; - -ContentEditableInput.prototype.receivedFocus = function () { - var input = this - if (this.selectionInEditor()) - { this.pollSelection() } - else - { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }) } - - function poll() { - if (input.cm.state.focused) { - input.pollSelection() - input.polling.set(input.cm.options.pollInterval, poll) - } - } - this.polling.set(this.cm.options.pollInterval, poll) -}; - -ContentEditableInput.prototype.selectionChanged = function () { - var sel = window.getSelection() - return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || - sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset -}; - -ContentEditableInput.prototype.pollSelection = function () { - if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return } - var sel = window.getSelection(), cm = this.cm - // On Android Chrome (version 56, at least), backspacing into an - // uneditable block element will put the cursor in that element, - // and then, because it's not editable, hide the virtual keyboard. - // Because Android doesn't allow us to actually detect backspace - // presses in a sane way, this code checks for when that happens - // and simulates a backspace press in this case. - if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) { - this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs}) - this.blur() - this.focus() - return - } - if (this.composing) { return } - this.rememberSelection() - var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset) - var head = domToPos(cm, sel.focusNode, sel.focusOffset) - if (anchor && head) { runInOp(cm, function () { - setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll) - if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true } - }) } -}; - -ContentEditableInput.prototype.pollContent = function () { - if (this.readDOMTimeout != null) { - clearTimeout(this.readDOMTimeout) - this.readDOMTimeout = null - } - - var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary() - var from = sel.from(), to = sel.to() - if (from.ch == 0 && from.line > cm.firstLine()) - { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length) } - if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine()) - { to = Pos(to.line + 1, 0) } - if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false } - - var fromIndex, fromLine, fromNode - if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { - fromLine = lineNo(display.view[0].line) - fromNode = display.view[0].node - } else { - fromLine = lineNo(display.view[fromIndex].line) - fromNode = display.view[fromIndex - 1].node.nextSibling - } - var toIndex = findViewIndex(cm, to.line) - var toLine, toNode - if (toIndex == display.view.length - 1) { - toLine = display.viewTo - 1 - toNode = display.lineDiv.lastChild - } else { - toLine = lineNo(display.view[toIndex + 1].line) - 1 - toNode = display.view[toIndex + 1].node.previousSibling - } - - if (!fromNode) { return false } - var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)) - var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)) - while (newText.length > 1 && oldText.length > 1) { - if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine-- } - else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++ } - else { break } - } - - var cutFront = 0, cutEnd = 0 - var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length) - while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) - { ++cutFront } - var newBot = lst(newText), oldBot = lst(oldText) - var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), - oldBot.length - (oldText.length == 1 ? cutFront : 0)) - while (cutEnd < maxCutEnd && - newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) - { ++cutEnd } - // Try to move start of change to start of selection if ambiguous - if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) { - while (cutFront && cutFront > from.ch && - newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) { - cutFront-- - cutEnd++ - } - } - - newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "") - newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "") - - var chFrom = Pos(fromLine, cutFront) - var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0) - if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { - replaceRange(cm.doc, newText, chFrom, chTo, "+input") - return true - } -}; - -ContentEditableInput.prototype.ensurePolled = function () { - this.forceCompositionEnd() -}; -ContentEditableInput.prototype.reset = function () { - this.forceCompositionEnd() -}; -ContentEditableInput.prototype.forceCompositionEnd = function () { - if (!this.composing) { return } - clearTimeout(this.readDOMTimeout) - this.composing = null - this.updateFromDOM() - this.div.blur() - this.div.focus() -}; -ContentEditableInput.prototype.readFromDOMSoon = function () { - var this$1 = this; - - if (this.readDOMTimeout != null) { return } - this.readDOMTimeout = setTimeout(function () { - this$1.readDOMTimeout = null - if (this$1.composing) { - if (this$1.composing.done) { this$1.composing = null } - else { return } - } - this$1.updateFromDOM() - }, 80) -}; - -ContentEditableInput.prototype.updateFromDOM = function () { - var this$1 = this; - - if (this.cm.isReadOnly() || !this.pollContent()) - { runInOp(this.cm, function () { return regChange(this$1.cm); }) } -}; - -ContentEditableInput.prototype.setUneditable = function (node) { - node.contentEditable = "false" -}; - -ContentEditableInput.prototype.onKeyPress = function (e) { - if (e.charCode == 0) { return } - e.preventDefault() - if (!this.cm.isReadOnly()) - { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) } -}; - -ContentEditableInput.prototype.readOnlyChanged = function (val) { - this.div.contentEditable = String(val != "nocursor") -}; - -ContentEditableInput.prototype.onContextMenu = function () {}; -ContentEditableInput.prototype.resetPosition = function () {}; - -ContentEditableInput.prototype.needsContentAttribute = true - -function posToDOM(cm, pos) { - var view = findViewForLine(cm, pos.line) - if (!view || view.hidden) { return null } - var line = getLine(cm.doc, pos.line) - var info = mapFromLineView(view, line, pos.line) - - var order = getOrder(line, cm.doc.direction), side = "left" - if (order) { - var partPos = getBidiPartAt(order, pos.ch) - side = partPos % 2 ? "right" : "left" - } - var result = nodeAndOffsetInLineMap(info.map, pos.ch, side) - result.offset = result.collapse == "right" ? result.end : result.start - return result -} - -function isInGutter(node) { - for (var scan = node; scan; scan = scan.parentNode) - { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } } - return false -} - -function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos } - -function domTextBetween(cm, from, to, fromLine, toLine) { - var text = "", closing = false, lineSep = cm.doc.lineSeparator() - function recognizeMarker(id) { return function (marker) { return marker.id == id; } } - function close() { - if (closing) { - text += lineSep - closing = false - } - } - function addText(str) { - if (str) { - close() - text += str - } - } - function walk(node) { - if (node.nodeType == 1) { - var cmText = node.getAttribute("cm-text") - if (cmText != null) { - addText(cmText || node.textContent.replace(/\u200b/g, "")) - return - } - var markerID = node.getAttribute("cm-marker"), range - if (markerID) { - var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)) - if (found.length && (range = found[0].find())) - { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) } - return - } - if (node.getAttribute("contenteditable") == "false") { return } - var isBlock = /^(pre|div|p)$/i.test(node.nodeName) - if (isBlock) { close() } - for (var i = 0; i < node.childNodes.length; i++) - { walk(node.childNodes[i]) } - if (isBlock) { closing = true } - } else if (node.nodeType == 3) { - addText(node.nodeValue) - } - } - for (;;) { - walk(from) - if (from == to) { break } - from = from.nextSibling - } - return text -} - -function domToPos(cm, node, offset) { - var lineNode - if (node == cm.display.lineDiv) { - lineNode = cm.display.lineDiv.childNodes[offset] - if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) } - node = null; offset = 0 - } else { - for (lineNode = node;; lineNode = lineNode.parentNode) { - if (!lineNode || lineNode == cm.display.lineDiv) { return null } - if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break } - } - } - for (var i = 0; i < cm.display.view.length; i++) { - var lineView = cm.display.view[i] - if (lineView.node == lineNode) - { return locateNodeInLineView(lineView, node, offset) } - } -} - -function locateNodeInLineView(lineView, node, offset) { - var wrapper = lineView.text.firstChild, bad = false - if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) } - if (node == wrapper) { - bad = true - node = wrapper.childNodes[offset] - offset = 0 - if (!node) { - var line = lineView.rest ? lst(lineView.rest) : lineView.line - return badPos(Pos(lineNo(line), line.text.length), bad) - } - } - - var textNode = node.nodeType == 3 ? node : null, topNode = node - if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { - textNode = node.firstChild - if (offset) { offset = textNode.nodeValue.length } - } - while (topNode.parentNode != wrapper) { topNode = topNode.parentNode } - var measure = lineView.measure, maps = measure.maps - - function find(textNode, topNode, offset) { - for (var i = -1; i < (maps ? maps.length : 0); i++) { - var map = i < 0 ? measure.map : maps[i] - for (var j = 0; j < map.length; j += 3) { - var curNode = map[j + 2] - if (curNode == textNode || curNode == topNode) { - var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]) - var ch = map[j] + offset - if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)] } - return Pos(line, ch) - } - } - } - } - var found = find(textNode, topNode, offset) - if (found) { return badPos(found, bad) } - - // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems - for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { - found = find(after, after.firstChild, 0) - if (found) - { return badPos(Pos(found.line, found.ch - dist), bad) } - else - { dist += after.textContent.length } - } - for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) { - found = find(before, before.firstChild, -1) - if (found) - { return badPos(Pos(found.line, found.ch + dist$1), bad) } - else - { dist$1 += before.textContent.length } - } -} - -// TEXTAREA INPUT STYLE - -var TextareaInput = function(cm) { - this.cm = cm - // See input.poll and input.reset - this.prevInput = "" - - // Flag that indicates whether we expect input to appear real soon - // now (after some event like 'keypress' or 'input') and are - // polling intensively. - this.pollingFast = false - // Self-resetting timeout for the poller - this.polling = new Delayed() - // Used to work around IE issue with selection being forgotten when focus moves away from textarea - this.hasSelection = false - this.composing = null -}; - -TextareaInput.prototype.init = function (display) { - var this$1 = this; - - var input = this, cm = this.cm - - // Wraps and hides input textarea - var div = this.wrapper = hiddenTextarea() - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var te = this.textarea = div.firstChild - display.wrapper.insertBefore(div, display.wrapper.firstChild) - - // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) - if (ios) { te.style.width = "0px" } - - on(te, "input", function () { - if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null } - input.poll() - }) - - on(te, "paste", function (e) { - if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } - - cm.state.pasteIncoming = true - input.fastPoll() - }) - - function prepareCopyCut(e) { - if (signalDOMEvent(cm, e)) { return } - if (cm.somethingSelected()) { - setLastCopied({lineWise: false, text: cm.getSelections()}) - } else if (!cm.options.lineWiseCopyCut) { - return - } else { - var ranges = copyableRanges(cm) - setLastCopied({lineWise: true, text: ranges.text}) - if (e.type == "cut") { - cm.setSelections(ranges.ranges, null, sel_dontScroll) - } else { - input.prevInput = "" - te.value = ranges.text.join("\n") - selectInput(te) - } - } - if (e.type == "cut") { cm.state.cutIncoming = true } - } - on(te, "cut", prepareCopyCut) - on(te, "copy", prepareCopyCut) - - on(display.scroller, "paste", function (e) { - if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return } - cm.state.pasteIncoming = true - input.focus() - }) - - // Prevent normal selection in the editor (we handle our own) - on(display.lineSpace, "selectstart", function (e) { - if (!eventInWidget(display, e)) { e_preventDefault(e) } - }) - - on(te, "compositionstart", function () { - var start = cm.getCursor("from") - if (input.composing) { input.composing.range.clear() } - input.composing = { - start: start, - range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) - } - }) - on(te, "compositionend", function () { - if (input.composing) { - input.poll() - input.composing.range.clear() - input.composing = null - } - }) -}; - -TextareaInput.prototype.prepareSelection = function () { - // Redraw the selection and/or cursor - var cm = this.cm, display = cm.display, doc = cm.doc - var result = prepareSelection(cm) - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, doc.sel.primary().head, "div") - var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect() - result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)) - result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)) - } - - return result -}; - -TextareaInput.prototype.showSelection = function (drawn) { - var cm = this.cm, display = cm.display - removeChildrenAndAdd(display.cursorDiv, drawn.cursors) - removeChildrenAndAdd(display.selectionDiv, drawn.selection) - if (drawn.teTop != null) { - this.wrapper.style.top = drawn.teTop + "px" - this.wrapper.style.left = drawn.teLeft + "px" - } -}; - -// Reset the input to correspond to the selection (or to be empty, -// when not typing and nothing is selected) -TextareaInput.prototype.reset = function (typing) { - if (this.contextMenuPending || this.composing) { return } - var cm = this.cm - if (cm.somethingSelected()) { - this.prevInput = "" - var content = cm.getSelection() - this.textarea.value = content - if (cm.state.focused) { selectInput(this.textarea) } - if (ie && ie_version >= 9) { this.hasSelection = content } - } else if (!typing) { - this.prevInput = this.textarea.value = "" - if (ie && ie_version >= 9) { this.hasSelection = null } - } -}; - -TextareaInput.prototype.getField = function () { return this.textarea }; - -TextareaInput.prototype.supportsTouch = function () { return false }; - -TextareaInput.prototype.focus = function () { - if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { - try { this.textarea.focus() } - catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM - } -}; - -TextareaInput.prototype.blur = function () { this.textarea.blur() }; - -TextareaInput.prototype.resetPosition = function () { - this.wrapper.style.top = this.wrapper.style.left = 0 -}; - -TextareaInput.prototype.receivedFocus = function () { this.slowPoll() }; - -// Poll for input changes, using the normal rate of polling. This -// runs as long as the editor is focused. -TextareaInput.prototype.slowPoll = function () { - var this$1 = this; - - if (this.pollingFast) { return } - this.polling.set(this.cm.options.pollInterval, function () { - this$1.poll() - if (this$1.cm.state.focused) { this$1.slowPoll() } - }) -}; - -// When an event has just come in that is likely to add or change -// something in the input textarea, we poll faster, to ensure that -// the change appears on the screen quickly. -TextareaInput.prototype.fastPoll = function () { - var missed = false, input = this - input.pollingFast = true - function p() { - var changed = input.poll() - if (!changed && !missed) {missed = true; input.polling.set(60, p)} - else {input.pollingFast = false; input.slowPoll()} - } - input.polling.set(20, p) -}; - -// Read input from the textarea, and update the document to match. -// When something is selected, it is present in the textarea, and -// selected (unless it is huge, in which case a placeholder is -// used). When nothing is selected, the cursor sits after previously -// seen text (can be empty), which is stored in prevInput (we must -// not reset the textarea when typing, because that breaks IME). -TextareaInput.prototype.poll = function () { - var this$1 = this; - - var cm = this.cm, input = this.textarea, prevInput = this.prevInput - // Since this is called a *lot*, try to bail out as cheaply as - // possible when it is clear that nothing happened. hasSelection - // will be the case when there is a lot of text in the textarea, - // in which case reading its value would be expensive. - if (this.contextMenuPending || !cm.state.focused || - (hasSelection(input) && !prevInput && !this.composing) || - cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) - { return false } - - var text = input.value - // If nothing changed, bail. - if (text == prevInput && !cm.somethingSelected()) { return false } - // Work around nonsensical selection resetting in IE9/10, and - // inexplicable appearance of private area unicode characters on - // some key combos in Mac (#2689). - if (ie && ie_version >= 9 && this.hasSelection === text || - mac && /[\uf700-\uf7ff]/.test(text)) { - cm.display.input.reset() - return false - } - - if (cm.doc.sel == cm.display.selForContextMenu) { - var first = text.charCodeAt(0) - if (first == 0x200b && !prevInput) { prevInput = "\u200b" } - if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") } - } - // Find the part of the input that is actually new - var same = 0, l = Math.min(prevInput.length, text.length) - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same } - - runInOp(cm, function () { - applyTextInput(cm, text.slice(same), prevInput.length - same, - null, this$1.composing ? "*compose" : null) - - // Don't leave long text in the textarea, since it makes further polling slow - if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = "" } - else { this$1.prevInput = text } - - if (this$1.composing) { - this$1.composing.range.clear() - this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"), - {className: "CodeMirror-composing"}) - } - }) - return true -}; - -TextareaInput.prototype.ensurePolled = function () { - if (this.pollingFast && this.poll()) { this.pollingFast = false } -}; - -TextareaInput.prototype.onKeyPress = function () { - if (ie && ie_version >= 9) { this.hasSelection = null } - this.fastPoll() -}; - -TextareaInput.prototype.onContextMenu = function (e) { - var input = this, cm = input.cm, display = cm.display, te = input.textarea - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop - if (!pos || presto) { return } // Opera is difficult. - - // Reset the current text selection only if the click is done outside of the selection - // and 'resetSelectionOnContextMenu' option is true. - var reset = cm.options.resetSelectionOnContextMenu - if (reset && cm.doc.sel.contains(pos) == -1) - { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll) } - - var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText - input.wrapper.style.cssText = "position: absolute" - var wrapperBox = input.wrapper.getBoundingClientRect() - te.style.cssText = "position: absolute; width: 30px; height: 30px;\n top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);" - var oldScrollY - if (webkit) { oldScrollY = window.scrollY } // Work around Chrome issue (#2712) - display.input.focus() - if (webkit) { window.scrollTo(null, oldScrollY) } - display.input.reset() - // Adds "Select all" to context menu in FF - if (!cm.somethingSelected()) { te.value = input.prevInput = " " } - input.contextMenuPending = true - display.selForContextMenu = cm.doc.sel - clearTimeout(display.detectingSelectAll) - - // Select-all will be greyed out if there's nothing to select, so - // this adds a zero-width space so that we can later check whether - // it got selected. - function prepareSelectAllHack() { - if (te.selectionStart != null) { - var selected = cm.somethingSelected() - var extval = "\u200b" + (selected ? te.value : "") - te.value = "\u21da" // Used to catch context-menu undo - te.value = extval - input.prevInput = selected ? "" : "\u200b" - te.selectionStart = 1; te.selectionEnd = extval.length - // Re-set this, in case some other handler touched the - // selection in the meantime. - display.selForContextMenu = cm.doc.sel - } - } - function rehide() { - input.contextMenuPending = false - input.wrapper.style.cssText = oldWrapperCSS - te.style.cssText = oldCSS - if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos) } - - // Try to detect the user choosing select-all - if (te.selectionStart != null) { - if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack() } - var i = 0, poll = function () { - if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && - te.selectionEnd > 0 && input.prevInput == "\u200b") { - operation(cm, selectAll)(cm) - } else if (i++ < 10) { - display.detectingSelectAll = setTimeout(poll, 500) - } else { - display.selForContextMenu = null - display.input.reset() - } - } - display.detectingSelectAll = setTimeout(poll, 200) - } - } - - if (ie && ie_version >= 9) { prepareSelectAllHack() } - if (captureRightClick) { - e_stop(e) - var mouseup = function () { - off(window, "mouseup", mouseup) - setTimeout(rehide, 20) - } - on(window, "mouseup", mouseup) - } else { - setTimeout(rehide, 50) - } -}; - -TextareaInput.prototype.readOnlyChanged = function (val) { - if (!val) { this.reset() } - this.textarea.disabled = val == "nocursor" -}; - -TextareaInput.prototype.setUneditable = function () {}; - -TextareaInput.prototype.needsContentAttribute = false - -function fromTextArea(textarea, options) { - options = options ? copyObj(options) : {} - options.value = textarea.value - if (!options.tabindex && textarea.tabIndex) - { options.tabindex = textarea.tabIndex } - if (!options.placeholder && textarea.placeholder) - { options.placeholder = textarea.placeholder } - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = activeElt() - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body - } - - function save() {textarea.value = cm.getValue()} - - var realSubmit - if (textarea.form) { - on(textarea.form, "submit", save) - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form - realSubmit = form.submit - try { - var wrappedSubmit = form.submit = function () { - save() - form.submit = realSubmit - form.submit() - form.submit = wrappedSubmit - } - } catch(e) {} - } - } - - options.finishInit = function (cm) { - cm.save = save - cm.getTextArea = function () { return textarea; } - cm.toTextArea = function () { - cm.toTextArea = isNaN // Prevent this from being ran twice - save() - textarea.parentNode.removeChild(cm.getWrapperElement()) - textarea.style.display = "" - if (textarea.form) { - off(textarea.form, "submit", save) - if (typeof textarea.form.submit == "function") - { textarea.form.submit = realSubmit } - } - } - } - - textarea.style.display = "none" - var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); }, - options) - return cm -} - -function addLegacyProps(CodeMirror) { - CodeMirror.off = off - CodeMirror.on = on - CodeMirror.wheelEventPixels = wheelEventPixels - CodeMirror.Doc = Doc - CodeMirror.splitLines = splitLinesAuto - CodeMirror.countColumn = countColumn - CodeMirror.findColumn = findColumn - CodeMirror.isWordChar = isWordCharBasic - CodeMirror.Pass = Pass - CodeMirror.signal = signal - CodeMirror.Line = Line - CodeMirror.changeEnd = changeEnd - CodeMirror.scrollbarModel = scrollbarModel - CodeMirror.Pos = Pos - CodeMirror.cmpPos = cmp - CodeMirror.modes = modes - CodeMirror.mimeModes = mimeModes - CodeMirror.resolveMode = resolveMode - CodeMirror.getMode = getMode - CodeMirror.modeExtensions = modeExtensions - CodeMirror.extendMode = extendMode - CodeMirror.copyState = copyState - CodeMirror.startState = startState - CodeMirror.innerMode = innerMode - CodeMirror.commands = commands - CodeMirror.keyMap = keyMap - CodeMirror.keyName = keyName - CodeMirror.isModifierKey = isModifierKey - CodeMirror.lookupKey = lookupKey - CodeMirror.normalizeKeyMap = normalizeKeyMap - CodeMirror.StringStream = StringStream - CodeMirror.SharedTextMarker = SharedTextMarker - CodeMirror.TextMarker = TextMarker - CodeMirror.LineWidget = LineWidget - CodeMirror.e_preventDefault = e_preventDefault - CodeMirror.e_stopPropagation = e_stopPropagation - CodeMirror.e_stop = e_stop - CodeMirror.addClass = addClass - CodeMirror.contains = contains - CodeMirror.rmClass = rmClass - CodeMirror.keyNames = keyNames -} - -// EDITOR CONSTRUCTOR - -defineOptions(CodeMirror) - -addEditorMethods(CodeMirror) - -// Set up methods on CodeMirror's prototype to redirect to the editor's document. -var dontDelegate = "iter insert remove copy getEditor constructor".split(" ") -for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - { CodeMirror.prototype[prop] = (function(method) { - return function() {return method.apply(this.doc, arguments)} - })(Doc.prototype[prop]) } } - -eventMixin(Doc) - -// INPUT HANDLING - -CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput} - -// MODE DEFINITION AND QUERYING - -// Extra arguments are stored as the mode's dependencies, which is -// used by (legacy) mechanisms like loadmode.js to automatically -// load a mode. (Preferred mechanism is the require/define calls.) -CodeMirror.defineMode = function(name/*, mode, …*/) { - if (!CodeMirror.defaults.mode && name != "null") { CodeMirror.defaults.mode = name } - defineMode.apply(this, arguments) -} - -CodeMirror.defineMIME = defineMIME - -// Minimal default mode. -CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }) -CodeMirror.defineMIME("text/plain", "null") - -// EXTENSIONS - -CodeMirror.defineExtension = function (name, func) { - CodeMirror.prototype[name] = func -} -CodeMirror.defineDocExtension = function (name, func) { - Doc.prototype[name] = func -} - -CodeMirror.fromTextArea = fromTextArea - -addLegacyProps(CodeMirror) - -CodeMirror.version = "5.28.0" - -return CodeMirror; - -}))); \ No newline at end of file diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/css.js b/js/DevHelper/Lib/CodeMirror/mode/css/css.js deleted file mode 100644 index 056c48e..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/css.js +++ /dev/null @@ -1,830 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("css", function(config, parserConfig) { - var inline = parserConfig.inline - if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); - - var indentUnit = config.indentUnit, - tokenHooks = parserConfig.tokenHooks, - documentTypes = parserConfig.documentTypes || {}, - mediaTypes = parserConfig.mediaTypes || {}, - mediaFeatures = parserConfig.mediaFeatures || {}, - mediaValueKeywords = parserConfig.mediaValueKeywords || {}, - propertyKeywords = parserConfig.propertyKeywords || {}, - nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {}, - fontProperties = parserConfig.fontProperties || {}, - counterDescriptors = parserConfig.counterDescriptors || {}, - colorKeywords = parserConfig.colorKeywords || {}, - valueKeywords = parserConfig.valueKeywords || {}, - allowNested = parserConfig.allowNested, - lineComment = parserConfig.lineComment, - supportsAtComponent = parserConfig.supportsAtComponent === true; - - var type, override; - function ret(style, tp) { type = tp; return style; } - - // Tokenizers - - function tokenBase(stream, state) { - var ch = stream.next(); - if (tokenHooks[ch]) { - var result = tokenHooks[ch](stream, state); - if (result !== false) return result; - } - if (ch == "@") { - stream.eatWhile(/[\w\\\-]/); - return ret("def", stream.current()); - } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) { - return ret(null, "compare"); - } else if (ch == "\"" || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "#") { - stream.eatWhile(/[\w\\\-]/); - return ret("atom", "hash"); - } else if (ch == "!") { - stream.match(/^\s*\w*/); - return ret("keyword", "important"); - } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } else if (ch === "-") { - if (/[\d.]/.test(stream.peek())) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } else if (stream.match(/^-[\w\\\-]+/)) { - stream.eatWhile(/[\w\\\-]/); - if (stream.match(/^\s*:/, false)) - return ret("variable-2", "variable-definition"); - return ret("variable-2", "variable"); - } else if (stream.match(/^\w+-/)) { - return ret("meta", "meta"); - } - } else if (/[,+>*\/]/.test(ch)) { - return ret(null, "select-op"); - } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { - return ret("qualifier", "qualifier"); - } else if (/[:;{}\[\]\(\)]/.test(ch)) { - return ret(null, ch); - } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || - (ch == "d" && stream.match("omain(")) || - (ch == "r" && stream.match("egexp("))) { - stream.backUp(1); - state.tokenize = tokenParenthesized; - return ret("property", "word"); - } else if (/[\w\\\-]/.test(ch)) { - stream.eatWhile(/[\w\\\-]/); - return ret("property", "word"); - } else { - return ret(null, null); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) { - if (quote == ")") stream.backUp(1); - break; - } - escaped = !escaped && ch == "\\"; - } - if (ch == quote || !escaped && quote != ")") state.tokenize = null; - return ret("string", "string"); - }; - } - - function tokenParenthesized(stream, state) { - stream.next(); // Must be '(' - if (!stream.match(/\s*[\"\')]/, false)) - state.tokenize = tokenString(")"); - else - state.tokenize = null; - return ret(null, "("); - } - - // Context management - - function Context(type, indent, prev) { - this.type = type; - this.indent = indent; - this.prev = prev; - } - - function pushContext(state, stream, type, indent) { - state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context); - return type; - } - - function popContext(state) { - if (state.context.prev) - state.context = state.context.prev; - return state.context.type; - } - - function pass(type, stream, state) { - return states[state.context.type](type, stream, state); - } - function popAndPass(type, stream, state, n) { - for (var i = n || 1; i > 0; i--) - state.context = state.context.prev; - return pass(type, stream, state); - } - - // Parser - - function wordAsValue(stream) { - var word = stream.current().toLowerCase(); - if (valueKeywords.hasOwnProperty(word)) - override = "atom"; - else if (colorKeywords.hasOwnProperty(word)) - override = "keyword"; - else - override = "variable"; - } - - var states = {}; - - states.top = function(type, stream, state) { - if (type == "{") { - return pushContext(state, stream, "block"); - } else if (type == "}" && state.context.prev) { - return popContext(state); - } else if (supportsAtComponent && /@component/.test(type)) { - return pushContext(state, stream, "atComponentBlock"); - } else if (/^@(-moz-)?document$/.test(type)) { - return pushContext(state, stream, "documentTypes"); - } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { - return pushContext(state, stream, "atBlock"); - } else if (/^@(font-face|counter-style)/.test(type)) { - state.stateArg = type; - return "restricted_atBlock_before"; - } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { - return "keyframes"; - } else if (type && type.charAt(0) == "@") { - return pushContext(state, stream, "at"); - } else if (type == "hash") { - override = "builtin"; - } else if (type == "word") { - override = "tag"; - } else if (type == "variable-definition") { - return "maybeprop"; - } else if (type == "interpolation") { - return pushContext(state, stream, "interpolation"); - } else if (type == ":") { - return "pseudo"; - } else if (allowNested && type == "(") { - return pushContext(state, stream, "parens"); - } - return state.context.type; - }; - - states.block = function(type, stream, state) { - if (type == "word") { - var word = stream.current().toLowerCase(); - if (propertyKeywords.hasOwnProperty(word)) { - override = "property"; - return "maybeprop"; - } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { - override = "string-2"; - return "maybeprop"; - } else if (allowNested) { - override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; - return "block"; - } else { - override += " error"; - return "maybeprop"; - } - } else if (type == "meta") { - return "block"; - } else if (!allowNested && (type == "hash" || type == "qualifier")) { - override = "error"; - return "block"; - } else { - return states.top(type, stream, state); - } - }; - - states.maybeprop = function(type, stream, state) { - if (type == ":") return pushContext(state, stream, "prop"); - return pass(type, stream, state); - }; - - states.prop = function(type, stream, state) { - if (type == ";") return popContext(state); - if (type == "{" && allowNested) return pushContext(state, stream, "propBlock"); - if (type == "}" || type == "{") return popAndPass(type, stream, state); - if (type == "(") return pushContext(state, stream, "parens"); - - if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) { - override += " error"; - } else if (type == "word") { - wordAsValue(stream); - } else if (type == "interpolation") { - return pushContext(state, stream, "interpolation"); - } - return "prop"; - }; - - states.propBlock = function(type, _stream, state) { - if (type == "}") return popContext(state); - if (type == "word") { override = "property"; return "maybeprop"; } - return state.context.type; - }; - - states.parens = function(type, stream, state) { - if (type == "{" || type == "}") return popAndPass(type, stream, state); - if (type == ")") return popContext(state); - if (type == "(") return pushContext(state, stream, "parens"); - if (type == "interpolation") return pushContext(state, stream, "interpolation"); - if (type == "word") wordAsValue(stream); - return "parens"; - }; - - states.pseudo = function(type, stream, state) { - if (type == "meta") return "pseudo"; - - if (type == "word") { - override = "variable-3"; - return state.context.type; - } - return pass(type, stream, state); - }; - - states.documentTypes = function(type, stream, state) { - if (type == "word" && documentTypes.hasOwnProperty(stream.current())) { - override = "tag"; - return state.context.type; - } else { - return states.atBlock(type, stream, state); - } - }; - - states.atBlock = function(type, stream, state) { - if (type == "(") return pushContext(state, stream, "atBlock_parens"); - if (type == "}" || type == ";") return popAndPass(type, stream, state); - if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top"); - - if (type == "interpolation") return pushContext(state, stream, "interpolation"); - - if (type == "word") { - var word = stream.current().toLowerCase(); - if (word == "only" || word == "not" || word == "and" || word == "or") - override = "keyword"; - else if (mediaTypes.hasOwnProperty(word)) - override = "attribute"; - else if (mediaFeatures.hasOwnProperty(word)) - override = "property"; - else if (mediaValueKeywords.hasOwnProperty(word)) - override = "keyword"; - else if (propertyKeywords.hasOwnProperty(word)) - override = "property"; - else if (nonStandardPropertyKeywords.hasOwnProperty(word)) - override = "string-2"; - else if (valueKeywords.hasOwnProperty(word)) - override = "atom"; - else if (colorKeywords.hasOwnProperty(word)) - override = "keyword"; - else - override = "error"; - } - return state.context.type; - }; - - states.atComponentBlock = function(type, stream, state) { - if (type == "}") - return popAndPass(type, stream, state); - if (type == "{") - return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false); - if (type == "word") - override = "error"; - return state.context.type; - }; - - states.atBlock_parens = function(type, stream, state) { - if (type == ")") return popContext(state); - if (type == "{" || type == "}") return popAndPass(type, stream, state, 2); - return states.atBlock(type, stream, state); - }; - - states.restricted_atBlock_before = function(type, stream, state) { - if (type == "{") - return pushContext(state, stream, "restricted_atBlock"); - if (type == "word" && state.stateArg == "@counter-style") { - override = "variable"; - return "restricted_atBlock_before"; - } - return pass(type, stream, state); - }; - - states.restricted_atBlock = function(type, stream, state) { - if (type == "}") { - state.stateArg = null; - return popContext(state); - } - if (type == "word") { - if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) || - (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase()))) - override = "error"; - else - override = "property"; - return "maybeprop"; - } - return "restricted_atBlock"; - }; - - states.keyframes = function(type, stream, state) { - if (type == "word") { override = "variable"; return "keyframes"; } - if (type == "{") return pushContext(state, stream, "top"); - return pass(type, stream, state); - }; - - states.at = function(type, stream, state) { - if (type == ";") return popContext(state); - if (type == "{" || type == "}") return popAndPass(type, stream, state); - if (type == "word") override = "tag"; - else if (type == "hash") override = "builtin"; - return "at"; - }; - - states.interpolation = function(type, stream, state) { - if (type == "}") return popContext(state); - if (type == "{" || type == ";") return popAndPass(type, stream, state); - if (type == "word") override = "variable"; - else if (type != "variable" && type != "(" && type != ")") override = "error"; - return "interpolation"; - }; - - return { - startState: function(base) { - return {tokenize: null, - state: inline ? "block" : "top", - stateArg: null, - context: new Context(inline ? "block" : "top", base || 0, null)}; - }, - - token: function(stream, state) { - if (!state.tokenize && stream.eatSpace()) return null; - var style = (state.tokenize || tokenBase)(stream, state); - if (style && typeof style == "object") { - type = style[1]; - style = style[0]; - } - override = style; - state.state = states[state.state](type, stream, state); - return override; - }, - - indent: function(state, textAfter) { - var cx = state.context, ch = textAfter && textAfter.charAt(0); - var indent = cx.indent; - if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev; - if (cx.prev) { - if (ch == "}" && (cx.type == "block" || cx.type == "top" || - cx.type == "interpolation" || cx.type == "restricted_atBlock")) { - // Resume indentation from parent context. - cx = cx.prev; - indent = cx.indent; - } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") || - ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { - // Dedent relative to current context. - indent = Math.max(0, cx.indent - indentUnit); - } - } - return indent; - }, - - electricChars: "}", - blockCommentStart: "/*", - blockCommentEnd: "*/", - lineComment: lineComment, - fold: "brace" - }; -}); - - function keySet(array) { - var keys = {}; - for (var i = 0; i < array.length; ++i) { - keys[array[i].toLowerCase()] = true; - } - return keys; - } - - var documentTypes_ = [ - "domain", "regexp", "url", "url-prefix" - ], documentTypes = keySet(documentTypes_); - - var mediaTypes_ = [ - "all", "aural", "braille", "handheld", "print", "projection", "screen", - "tty", "tv", "embossed" - ], mediaTypes = keySet(mediaTypes_); - - var mediaFeatures_ = [ - "width", "min-width", "max-width", "height", "min-height", "max-height", - "device-width", "min-device-width", "max-device-width", "device-height", - "min-device-height", "max-device-height", "aspect-ratio", - "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", - "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", - "max-color", "color-index", "min-color-index", "max-color-index", - "monochrome", "min-monochrome", "max-monochrome", "resolution", - "min-resolution", "max-resolution", "scan", "grid", "orientation", - "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", - "pointer", "any-pointer", "hover", "any-hover" - ], mediaFeatures = keySet(mediaFeatures_); - - var mediaValueKeywords_ = [ - "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", - "interlace", "progressive" - ], mediaValueKeywords = keySet(mediaValueKeywords_); - - var propertyKeywords_ = [ - "align-content", "align-items", "align-self", "alignment-adjust", - "alignment-baseline", "anchor-point", "animation", "animation-delay", - "animation-direction", "animation-duration", "animation-fill-mode", - "animation-iteration-count", "animation-name", "animation-play-state", - "animation-timing-function", "appearance", "azimuth", "backface-visibility", - "background", "background-attachment", "background-blend-mode", "background-clip", - "background-color", "background-image", "background-origin", "background-position", - "background-repeat", "background-size", "baseline-shift", "binding", - "bleed", "bookmark-label", "bookmark-level", "bookmark-state", - "bookmark-target", "border", "border-bottom", "border-bottom-color", - "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", - "border-color", "border-image", "border-image-outset", - "border-image-repeat", "border-image-slice", "border-image-source", - "border-image-width", "border-left", "border-left-color", - "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", - "border-spacing", "border-style", "border-top", "border-top-color", - "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "box-decoration-break", - "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", - "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count", - "column-fill", "column-gap", "column-rule", "column-rule-color", - "column-rule-style", "column-rule-width", "column-span", "column-width", - "columns", "content", "counter-increment", "counter-reset", "crop", "cue", - "cue-after", "cue-before", "cursor", "direction", "display", - "dominant-baseline", "drop-initial-after-adjust", - "drop-initial-after-align", "drop-initial-before-adjust", - "drop-initial-before-align", "drop-initial-size", "drop-initial-value", - "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", - "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", - "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", - "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", - "font-stretch", "font-style", "font-synthesis", "font-variant", - "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", - "font-variant-ligatures", "font-variant-numeric", "font-variant-position", - "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", - "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap", - "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap", - "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns", - "grid-template-rows", "hanging-punctuation", "height", "hyphens", - "icon", "image-orientation", "image-rendering", "image-resolution", - "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing", - "line-break", "line-height", "line-stacking", "line-stacking-ruby", - "line-stacking-shift", "line-stacking-strategy", "list-style", - "list-style-image", "list-style-position", "list-style-type", "margin", - "margin-bottom", "margin-left", "margin-right", "margin-top", - "marks", "marquee-direction", "marquee-loop", - "marquee-play-count", "marquee-speed", "marquee-style", "max-height", - "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", - "nav-left", "nav-right", "nav-up", "object-fit", "object-position", - "opacity", "order", "orphans", "outline", - "outline-color", "outline-offset", "outline-style", "outline-width", - "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", - "page", "page-break-after", "page-break-before", "page-break-inside", - "page-policy", "pause", "pause-after", "pause-before", "perspective", - "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position", - "presentation-level", "punctuation-trim", "quotes", "region-break-after", - "region-break-before", "region-break-inside", "region-fragment", - "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", - "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", - "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", - "shape-outside", "size", "speak", "speak-as", "speak-header", - "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", - "tab-size", "table-layout", "target", "target-name", "target-new", - "target-position", "text-align", "text-align-last", "text-decoration", - "text-decoration-color", "text-decoration-line", "text-decoration-skip", - "text-decoration-style", "text-emphasis", "text-emphasis-color", - "text-emphasis-position", "text-emphasis-style", "text-height", - "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", - "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", - "text-wrap", "top", "transform", "transform-origin", "transform-style", - "transition", "transition-delay", "transition-duration", - "transition-property", "transition-timing-function", "unicode-bidi", - "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration", - "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", - "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break", - "word-spacing", "word-wrap", "z-index", - // SVG-specific - "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", - "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", - "color-interpolation", "color-interpolation-filters", - "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", - "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", - "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", - "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", - "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", - "glyph-orientation-vertical", "text-anchor", "writing-mode" - ], propertyKeywords = keySet(propertyKeywords_); - - var nonStandardPropertyKeywords_ = [ - "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color", - "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", - "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", - "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", - "searchfield-results-decoration", "zoom" - ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); - - var fontProperties_ = [ - "font-family", "src", "unicode-range", "font-variant", "font-feature-settings", - "font-stretch", "font-weight", "font-style" - ], fontProperties = keySet(fontProperties_); - - var counterDescriptors_ = [ - "additive-symbols", "fallback", "negative", "pad", "prefix", "range", - "speak-as", "suffix", "symbols", "system" - ], counterDescriptors = keySet(counterDescriptors_); - - var colorKeywords_ = [ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", - "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", - "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", - "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", - "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", - "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", - "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", - "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", - "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", - "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", - "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", - "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", - "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", - "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", - "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", - "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", - "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", - "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", - "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", - "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", - "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", - "whitesmoke", "yellow", "yellowgreen" - ], colorKeywords = keySet(colorKeywords_); - - var valueKeywords_ = [ - "above", "absolute", "activeborder", "additive", "activecaption", "afar", - "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", - "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", - "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page", - "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", - "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", - "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", - "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", - "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", - "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", - "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", - "compact", "condensed", "contain", "content", "contents", - "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", - "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", - "decimal-leading-zero", "default", "default-button", "dense", "destination-atop", - "destination-in", "destination-out", "destination-over", "devanagari", "difference", - "disc", "discard", "disclosure-closed", "disclosure-open", "document", - "dot-dash", "dot-dot-dash", - "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", - "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", - "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", - "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", - "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", - "ethiopic-halehame-gez", "ethiopic-halehame-om-et", - "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", - "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", - "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", - "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", - "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove", - "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", - "help", "hidden", "hide", "higher", "highlight", "highlighttext", - "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", - "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", - "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", - "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert", - "italic", "japanese-formal", "japanese-informal", "justify", "kannada", - "katakana", "katakana-iroha", "keep-all", "khmer", - "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", - "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten", - "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem", - "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", - "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", - "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", - "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", - "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", - "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", - "media-volume-slider-container", "media-volume-sliderthumb", "medium", - "menu", "menulist", "menulist-button", "menulist-text", - "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", - "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize", - "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", - "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", - "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote", - "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", - "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", - "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter", - "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", - "progress", "push-button", "radial-gradient", "radio", "read-only", - "read-write", "read-write-plaintext-only", "rectangle", "region", - "relative", "repeat", "repeating-linear-gradient", - "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", - "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", - "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", - "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", - "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield", - "searchfield-cancel-button", "searchfield-decoration", - "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end", - "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", - "simp-chinese-formal", "simp-chinese-informal", "single", - "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", - "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", - "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", - "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square", - "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", - "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table", - "table-caption", "table-cell", "table-column", "table-column-group", - "table-footer-group", "table-header-group", "table-row", "table-row-group", - "tamil", - "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", - "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", - "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", - "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", - "trad-chinese-formal", "trad-chinese-informal", "transform", - "translate", "translate3d", "translateX", "translateY", "translateZ", - "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up", - "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", - "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", - "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", - "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", - "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", - "xx-large", "xx-small" - ], valueKeywords = keySet(valueKeywords_); - - var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_) - .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_) - .concat(valueKeywords_); - CodeMirror.registerHelper("hintWords", "css", allWords); - - function tokenCComment(stream, state) { - var maybeEnd = false, ch; - while ((ch = stream.next()) != null) { - if (maybeEnd && ch == "/") { - state.tokenize = null; - break; - } - maybeEnd = (ch == "*"); - } - return ["comment", "comment"]; - } - - CodeMirror.defineMIME("text/css", { - documentTypes: documentTypes, - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - fontProperties: fontProperties, - counterDescriptors: counterDescriptors, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - tokenHooks: { - "/": function(stream, state) { - if (!stream.eat("*")) return false; - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - }, - name: "css" - }); - - CodeMirror.defineMIME("text/x-scss", { - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - fontProperties: fontProperties, - allowNested: true, - lineComment: "//", - tokenHooks: { - "/": function(stream, state) { - if (stream.eat("/")) { - stream.skipToEnd(); - return ["comment", "comment"]; - } else if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } else { - return ["operator", "operator"]; - } - }, - ":": function(stream) { - if (stream.match(/\s*\{/, false)) - return [null, null] - return false; - }, - "$": function(stream) { - stream.match(/^[\w-]+/); - if (stream.match(/^\s*:/, false)) - return ["variable-2", "variable-definition"]; - return ["variable-2", "variable"]; - }, - "#": function(stream) { - if (!stream.eat("{")) return false; - return [null, "interpolation"]; - } - }, - name: "css", - helperType: "scss" - }); - - CodeMirror.defineMIME("text/x-less", { - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - fontProperties: fontProperties, - allowNested: true, - lineComment: "//", - tokenHooks: { - "/": function(stream, state) { - if (stream.eat("/")) { - stream.skipToEnd(); - return ["comment", "comment"]; - } else if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } else { - return ["operator", "operator"]; - } - }, - "@": function(stream) { - if (stream.eat("{")) return [null, "interpolation"]; - if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; - stream.eatWhile(/[\w\\\-]/); - if (stream.match(/^\s*:/, false)) - return ["variable-2", "variable-definition"]; - return ["variable-2", "variable"]; - }, - "&": function() { - return ["atom", "atom"]; - } - }, - name: "css", - helperType: "less" - }); - - CodeMirror.defineMIME("text/x-gss", { - documentTypes: documentTypes, - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - fontProperties: fontProperties, - counterDescriptors: counterDescriptors, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - supportsAtComponent: true, - tokenHooks: { - "/": function(stream, state) { - if (!stream.eat("*")) return false; - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - }, - name: "css", - helperType: "gss" - }); - -}); diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/gss.html b/js/DevHelper/Lib/CodeMirror/mode/css/gss.html deleted file mode 100644 index 232fe8c..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/gss.html +++ /dev/null @@ -1,103 +0,0 @@ - - -CodeMirror: Closure Stylesheets (GSS) mode - - - - - - - - - - - - -
-

Closure Stylesheets (GSS) mode

-
- - -

A mode for Closure Stylesheets (GSS).

-

MIME type defined: text/x-gss.

- -

Parsing/Highlighting Tests: normal, verbose.

- -
diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/gss_test.js b/js/DevHelper/Lib/CodeMirror/mode/css/gss_test.js deleted file mode 100644 index d56e592..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/gss_test.js +++ /dev/null @@ -1,17 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - "use strict"; - - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); } - - MT("atComponent", - "[def @component] {", - "[tag foo] {", - " [property color]: [keyword black];", - "}", - "}"); - -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/index.html b/js/DevHelper/Lib/CodeMirror/mode/css/index.html deleted file mode 100644 index 0d85311..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - -CodeMirror: CSS mode - - - - - - - - - - - - -
-

CSS mode

-
- - -

MIME types defined: text/css, text/x-scss (demo), text/x-less (demo).

- -

Parsing/Highlighting Tests: normal, verbose.

- -
diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/less.html b/js/DevHelper/Lib/CodeMirror/mode/css/less.html deleted file mode 100644 index adf7427..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/less.html +++ /dev/null @@ -1,152 +0,0 @@ - - -CodeMirror: LESS mode - - - - - - - - - - -
-

LESS mode

-
- - -

The LESS mode is a sub-mode of the CSS mode (defined in css.js).

- -

Parsing/Highlighting Tests: normal, verbose.

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/less_test.js b/js/DevHelper/Lib/CodeMirror/mode/css/less_test.js deleted file mode 100644 index dd82155..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/less_test.js +++ /dev/null @@ -1,54 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - "use strict"; - - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); } - - MT("variable", - "[variable-2 @base]: [atom #f04615];", - "[qualifier .class] {", - " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]", - " [property color]: [variable saturate]([variable-2 @base], [number 5%]);", - "}"); - - MT("amp", - "[qualifier .child], [qualifier .sibling] {", - " [qualifier .parent] [atom &] {", - " [property color]: [keyword black];", - " }", - " [atom &] + [atom &] {", - " [property color]: [keyword red];", - " }", - "}"); - - MT("mixin", - "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", - " [property color]: [atom darken]([variable-2 @color], [number 10%]);", - "}", - "[qualifier .mixin] ([variable light]; [variable-2 @color]) {", - " [property color]: [atom lighten]([variable-2 @color], [number 10%]);", - "}", - "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {", - " [property display]: [atom block];", - "}", - "[variable-2 @switch]: [variable light];", - "[qualifier .class] {", - " [qualifier .mixin]([variable-2 @switch]; [atom #888]);", - "}"); - - MT("nest", - "[qualifier .one] {", - " [def @media] ([property width]: [number 400px]) {", - " [property font-size]: [number 1.2em];", - " [def @media] [attribute print] [keyword and] [property color] {", - " [property color]: [keyword blue];", - " }", - " }", - "}"); - - - MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }"); -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/scss.html b/js/DevHelper/Lib/CodeMirror/mode/css/scss.html deleted file mode 100644 index f8e4d37..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/scss.html +++ /dev/null @@ -1,157 +0,0 @@ - - -CodeMirror: SCSS mode - - - - - - - - - -
-

SCSS mode

-
- - -

The SCSS mode is a sub-mode of the CSS mode (defined in css.js).

- -

Parsing/Highlighting Tests: normal, verbose.

- -
diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/scss_test.js b/js/DevHelper/Lib/CodeMirror/mode/css/scss_test.js deleted file mode 100644 index 785921b..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/scss_test.js +++ /dev/null @@ -1,110 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } - - MT('url_with_quotation', - "[tag foo] { [property background]:[atom url]([string test.jpg]) }"); - - MT('url_with_double_quotes', - "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }"); - - MT('url_with_single_quotes', - "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }"); - - MT('string', - "[def @import] [string \"compass/css3\"]"); - - MT('important_keyword', - "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }"); - - MT('variable', - "[variable-2 $blue]:[atom #333]"); - - MT('variable_as_attribute', - "[tag foo] { [property color]:[variable-2 $blue] }"); - - MT('numbers', - "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }"); - - MT('number_percentage', - "[tag foo] { [property width]:[number 80%] }"); - - MT('selector', - "[builtin #hello][qualifier .world]{}"); - - MT('singleline_comment', - "[comment // this is a comment]"); - - MT('multiline_comment', - "[comment /*foobar*/]"); - - MT('attribute_with_hyphen', - "[tag foo] { [property font-size]:[number 10px] }"); - - MT('string_after_attribute', - "[tag foo] { [property content]:[string \"::\"] }"); - - MT('directives', - "[def @include] [qualifier .mixin]"); - - MT('basic_structure', - "[tag p] { [property background]:[keyword red]; }"); - - MT('nested_structure', - "[tag p] { [tag a] { [property color]:[keyword red]; } }"); - - MT('mixin', - "[def @mixin] [tag table-base] {}"); - - MT('number_without_semicolon', - "[tag p] {[property width]:[number 12]}", - "[tag a] {[property color]:[keyword red];}"); - - MT('atom_in_nested_block', - "[tag p] { [tag a] { [property color]:[atom #000]; } }"); - - MT('interpolation_in_property', - "[tag foo] { #{[variable-2 $hello]}:[number 2]; }"); - - MT('interpolation_in_selector', - "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }"); - - MT('interpolation_error', - "[tag foo]#{[variable foo]} { [property color]:[atom #000]; }"); - - MT("divide_operator", - "[tag foo] { [property width]:[number 4] [operator /] [number 2] }"); - - MT('nested_structure_with_id_selector', - "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }"); - - MT('indent_mixin', - "[def @mixin] [tag container] (", - " [variable-2 $a]: [number 10],", - " [variable-2 $b]: [number 10])", - "{}"); - - MT('indent_nested', - "[tag foo] {", - " [tag bar] {", - " }", - "}"); - - MT('indent_parentheses', - "[tag foo] {", - " [property color]: [atom darken]([variable-2 $blue],", - " [number 9%]);", - "}"); - - MT('indent_vardef', - "[variable-2 $name]:", - " [string 'val'];", - "[tag tag] {", - " [tag inner] {", - " [property margin]: [number 3px];", - " }", - "}"); -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/css/test.js b/js/DevHelper/Lib/CodeMirror/mode/css/test.js deleted file mode 100644 index 7a496fb..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/css/test.js +++ /dev/null @@ -1,200 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "css"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - // Error, because "foobarhello" is neither a known type or property, but - // property was expected (after "and"), and it should be in parentheses. - MT("atMediaUnknownType", - "[def @media] [attribute screen] [keyword and] [error foobarhello] { }"); - - // Soft error, because "foobarhello" is not a known property or type. - MT("atMediaUnknownProperty", - "[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }"); - - // Make sure nesting works with media queries - MT("atMediaMaxWidthNested", - "[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }"); - - MT("atMediaFeatureValueKeyword", - "[def @media] ([property orientation]: [keyword landscape]) { }"); - - MT("atMediaUnknownFeatureValueKeyword", - "[def @media] ([property orientation]: [error upsidedown]) { }"); - - MT("tagSelector", - "[tag foo] { }"); - - MT("classSelector", - "[qualifier .foo-bar_hello] { }"); - - MT("idSelector", - "[builtin #foo] { [error #foo] }"); - - MT("tagSelectorUnclosed", - "[tag foo] { [property margin]: [number 0] } [tag bar] { }"); - - MT("tagStringNoQuotes", - "[tag foo] { [property font-family]: [variable hello] [variable world]; }"); - - MT("tagStringDouble", - "[tag foo] { [property font-family]: [string \"hello world\"]; }"); - - MT("tagStringSingle", - "[tag foo] { [property font-family]: [string 'hello world']; }"); - - MT("tagColorKeyword", - "[tag foo] {", - " [property color]: [keyword black];", - " [property color]: [keyword navy];", - " [property color]: [keyword yellow];", - "}"); - - MT("tagColorHex3", - "[tag foo] { [property background]: [atom #fff]; }"); - - MT("tagColorHex4", - "[tag foo] { [property background]: [atom #ffff]; }"); - - MT("tagColorHex6", - "[tag foo] { [property background]: [atom #ffffff]; }"); - - MT("tagColorHex8", - "[tag foo] { [property background]: [atom #ffffffff]; }"); - - MT("tagColorHex5Invalid", - "[tag foo] { [property background]: [atom&error #fffff]; }"); - - MT("tagColorHexInvalid", - "[tag foo] { [property background]: [atom&error #ffg]; }"); - - MT("tagNegativeNumber", - "[tag foo] { [property margin]: [number -5px]; }"); - - MT("tagPositiveNumber", - "[tag foo] { [property padding]: [number 5px]; }"); - - MT("tagVendor", - "[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }"); - - MT("tagBogusProperty", - "[tag foo] { [property&error barhelloworld]: [number 0]; }"); - - MT("tagTwoProperties", - "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }"); - - MT("tagTwoPropertiesURL", - "[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }"); - - MT("indent_tagSelector", - "[tag strong], [tag em] {", - " [property background]: [atom rgba](", - " [number 255], [number 255], [number 0], [number .2]", - " );", - "}"); - - MT("indent_atMedia", - "[def @media] {", - " [tag foo] {", - " [property color]:", - " [keyword yellow];", - " }", - "}"); - - MT("indent_comma", - "[tag foo] {", - " [property font-family]: [variable verdana],", - " [atom sans-serif];", - "}"); - - MT("indent_parentheses", - "[tag foo]:[variable-3 before] {", - " [property background]: [atom url](", - "[string blahblah]", - "[string etc]", - "[string ]) [keyword !important];", - "}"); - - MT("font_face", - "[def @font-face] {", - " [property font-family]: [string 'myfont'];", - " [error nonsense]: [string 'abc'];", - " [property src]: [atom url]([string http://blah]),", - " [atom url]([string http://foo]);", - "}"); - - MT("empty_url", - "[def @import] [atom url]() [attribute screen];"); - - MT("parens", - "[qualifier .foo] {", - " [property background-image]: [variable fade]([atom #000], [number 20%]);", - " [property border-image]: [atom linear-gradient](", - " [atom to] [atom bottom],", - " [variable fade]([atom #000], [number 20%]) [number 0%],", - " [variable fade]([atom #000], [number 20%]) [number 100%]", - " );", - "}"); - - MT("css_variable", - ":[variable-3 root] {", - " [variable-2 --main-color]: [atom #06c];", - "}", - "[tag h1][builtin #foo] {", - " [property color]: [atom var]([variable-2 --main-color]);", - "}"); - - MT("supports", - "[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {", - " [property text-align-last]: [atom justify];", - "}"); - - MT("document", - "[def @document] [tag url]([string http://blah]),", - " [tag url-prefix]([string https://]),", - " [tag domain]([string blah.com]),", - " [tag regexp]([string \".*blah.+\"]) {", - " [builtin #id] {", - " [property background-color]: [keyword white];", - " }", - " [tag foo] {", - " [property font-family]: [variable Verdana], [atom sans-serif];", - " }", - "}"); - - MT("document_url", - "[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }"); - - MT("document_urlPrefix", - "[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }"); - - MT("document_domain", - "[def @document] [tag domain]([string blah.com]) { [tag foo] { } }"); - - MT("document_regexp", - "[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }"); - - MT("counter-style", - "[def @counter-style] [variable binary] {", - " [property system]: [atom numeric];", - " [property symbols]: [number 0] [number 1];", - " [property suffix]: [string \".\"];", - " [property range]: [atom infinite];", - " [property speak-as]: [atom numeric];", - "}"); - - MT("counter-style-additive-symbols", - "[def @counter-style] [variable simple-roman] {", - " [property system]: [atom additive];", - " [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];", - " [property range]: [number 1] [number 49];", - "}"); - - MT("counter-style-use", - "[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }"); - - MT("counter-style-symbols", - "[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }"); -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/htmlembedded.js b/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/htmlembedded.js deleted file mode 100644 index 464dc57..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/htmlembedded.js +++ /dev/null @@ -1,28 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), - require("../../addon/mode/multiplex")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../htmlmixed/htmlmixed", - "../../addon/mode/multiplex"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { - return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { - open: parserConfig.open || parserConfig.scriptStartRegex || "<%", - close: parserConfig.close || parserConfig.scriptEndRegex || "%>", - mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) - }); - }, "htmlmixed"); - - CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"}); - CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); - CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"}); - CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"}); -}); diff --git a/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/index.html b/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/index.html deleted file mode 100644 index 9ed33cf..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/htmlembedded/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - -CodeMirror: Html Embedded Scripts mode - - - - - - - - - - - - - - -
-

Html Embedded Scripts mode

-
- - - -

Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on - JavaScript, CSS and XML.
Other dependencies include those of the scripting language chosen.

- -

MIME types defined: application/x-aspx (ASP.NET), - application/x-ejs (Embedded Javascript), application/x-jsp (JavaServer Pages) - and application/x-erb

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/htmlmixed.js b/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/htmlmixed.js deleted file mode 100644 index 33398ec..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/htmlmixed.js +++ /dev/null @@ -1,152 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var defaultTags = { - script: [ - ["lang", /(javascript|babel)/i, "javascript"], - ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"], - ["type", /./, "text/plain"], - [null, null, "javascript"] - ], - style: [ - ["lang", /^css$/i, "css"], - ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"], - ["type", /./, "text/plain"], - [null, null, "css"] - ] - }; - - function maybeBackup(stream, pat, style) { - var cur = stream.current(), close = cur.search(pat); - if (close > -1) { - stream.backUp(cur.length - close); - } else if (cur.match(/<\/?$/)) { - stream.backUp(cur.length); - if (!stream.match(pat, false)) stream.match(cur); - } - return style; - } - - var attrRegexpCache = {}; - function getAttrRegexp(attr) { - var regexp = attrRegexpCache[attr]; - if (regexp) return regexp; - return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); - } - - function getAttrValue(text, attr) { - var match = text.match(getAttrRegexp(attr)) - return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : "" - } - - function getTagRegexp(tagName, anchored) { - return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); - } - - function addTags(from, to) { - for (var tag in from) { - var dest = to[tag] || (to[tag] = []); - var source = from[tag]; - for (var i = source.length - 1; i >= 0; i--) - dest.unshift(source[i]) - } - } - - function findMatchingMode(tagInfo, tagText) { - for (var i = 0; i < tagInfo.length; i++) { - var spec = tagInfo[i]; - if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2]; - } - } - - CodeMirror.defineMode("htmlmixed", function (config, parserConfig) { - var htmlMode = CodeMirror.getMode(config, { - name: "xml", - htmlMode: true, - multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, - multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag - }); - - var tags = {}; - var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes; - addTags(defaultTags, tags); - if (configTags) addTags(configTags, tags); - if (configScript) for (var i = configScript.length - 1; i >= 0; i--) - tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) - - function html(stream, state) { - var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName - if (tag && !/[<>\s\/]/.test(stream.current()) && - (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) && - tags.hasOwnProperty(tagName)) { - state.inTag = tagName + " " - } else if (state.inTag && tag && />$/.test(stream.current())) { - var inTag = /^([\S]+) (.*)/.exec(state.inTag) - state.inTag = null - var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2]) - var mode = CodeMirror.getMode(config, modeSpec) - var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false); - state.token = function (stream, state) { - if (stream.match(endTagA, false)) { - state.token = html; - state.localState = state.localMode = null; - return null; - } - return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); - }; - state.localMode = mode; - state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); - } else if (state.inTag) { - state.inTag += stream.current() - if (stream.eol()) state.inTag += " " - } - return style; - }; - - return { - startState: function () { - var state = CodeMirror.startState(htmlMode); - return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; - }, - - copyState: function (state) { - var local; - if (state.localState) { - local = CodeMirror.copyState(state.localMode, state.localState); - } - return {token: state.token, inTag: state.inTag, - localMode: state.localMode, localState: local, - htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; - }, - - token: function (stream, state) { - return state.token(stream, state); - }, - - indent: function (state, textAfter, line) { - if (!state.localMode || /^\s*<\//.test(textAfter)) - return htmlMode.indent(state.htmlState, textAfter); - else if (state.localMode.indent) - return state.localMode.indent(state.localState, textAfter, line); - else - return CodeMirror.Pass; - }, - - innerMode: function (state) { - return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; - } - }; - }, "xml", "javascript", "css"); - - CodeMirror.defineMIME("text/html", "htmlmixed"); -}); diff --git a/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/index.html b/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/index.html deleted file mode 100644 index caa7546..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/htmlmixed/index.html +++ /dev/null @@ -1,100 +0,0 @@ - - -CodeMirror: HTML mixed mode - - - - - - - - - - - - - - -
-

HTML mixed mode

-
- - -

The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

- -

It takes an optional mode configuration - option, tags, which can be used to add custom - behavior for specific tags. When given, it should be an object - mapping tag names (for example script) to arrays or - three-element arrays. Those inner arrays indicate [attributeName, - valueRegexp, modeSpec] - specifications. For example, you could use ["type", /^foo$/, - "foo"] to map the attribute type="foo" to - the foo mode. When the first two fields are null - ([null, null, "mode"]), the given mode is used for - any such tag that doesn't match any of the previously given - attributes. For example:

- -
var myModeSpec = {
-  name: "htmlmixed",
-  tags: {
-    style: [["type", /^text/(x-)?scss$/, "text/x-scss"],
-            [null, null, "css"]],
-    custom: [[null, null, "customMode"]]
-  }
-}
- -

MIME types defined: text/html - (redefined, only takes effect if you load this parser after the - XML parser).

- -
diff --git a/js/DevHelper/Lib/CodeMirror/mode/javascript/index.html b/js/DevHelper/Lib/CodeMirror/mode/javascript/index.html deleted file mode 100644 index 592a133..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/javascript/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - -CodeMirror: JavaScript mode - - - - - - - - - - - - -
-

JavaScript mode

- - -
- - - -

- JavaScript mode supports several configuration options: -

    -
  • json which will set the mode to expect JSON - data rather than a JavaScript program.
  • -
  • jsonld which will set the mode to expect - JSON-LD linked data rather - than a JavaScript program (demo).
  • -
  • typescript which will activate additional - syntax highlighting and some other things for TypeScript code - (demo).
  • -
  • statementIndent which (given a number) will - determine the amount of indentation to use for statements - continued on a new line.
  • -
  • wordCharacters, a regexp that indicates which - characters should be considered part of an identifier. - Defaults to /[\w$]/, which does not handle - non-ASCII identifiers. Can be set to something more elaborate - to improve Unicode support.
  • -
-

- -

MIME types defined: text/javascript, application/json, application/ld+json, text/typescript, application/typescript.

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/javascript/javascript.js b/js/DevHelper/Lib/CodeMirror/mode/javascript/javascript.js deleted file mode 100644 index 692ffc6..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/javascript/javascript.js +++ /dev/null @@ -1,818 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -function expressionAllowed(stream, state, backUp) { - return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) || - (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) -} - -CodeMirror.defineMode("javascript", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var statementIndent = parserConfig.statementIndent; - var jsonldMode = parserConfig.jsonld; - var jsonMode = parserConfig.json || jsonldMode; - var isTS = parserConfig.typescript; - var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; - - // Tokenizer - - var keywords = function(){ - function kw(type) {return {type: type, style: "keyword"};} - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - - var jsKeywords = { - "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, - "var": kw("var"), "const": kw("var"), "let": kw("var"), - "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, - "this": kw("this"), "class": kw("class"), "super": kw("atom"), - "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, - "await": C - }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "type"}; - var tsKeywords = { - // object-like things - "interface": kw("class"), - "implements": C, - "namespace": C, - "module": kw("module"), - "enum": kw("module"), - - // scope modifiers - "public": kw("modifier"), - "private": kw("modifier"), - "protected": kw("modifier"), - "abstract": kw("modifier"), - - // types - "string": type, "number": type, "boolean": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|~^@]/; - var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; - - function readRegexp(stream) { - var escaped = false, next, inSet = false; - while ((next = stream.next()) != null) { - if (!escaped) { - if (next == "/" && !inSet) return; - if (next == "[") inSet = true; - else if (inSet && next == "]") inSet = false; - } - escaped = !escaped && next == "\\"; - } - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { - return ret("number", "number"); - } else if (ch == "." && stream.match("..")) { - return ret("spread", "meta"); - } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - return ret(ch); - } else if (ch == "=" && stream.eat(">")) { - return ret("=>", "operator"); - } else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/o/i)) { - stream.eatWhile(/[0-7]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/b/i)) { - stream.eatWhile(/[01]/i); - return ret("number", "number"); - } else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); - return ret("number", "number"); - } else if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } else if (expressionAllowed(stream, state, 1)) { - readRegexp(stream); - stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); - return ret("regexp", "string-2"); - } else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } - } else if (ch == "`") { - state.tokenize = tokenQuasi; - return tokenQuasi(stream, state); - } else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } else if (isOperatorChar.test(ch)) { - if (ch != ">" || !state.lexical || state.lexical.type != ">") - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } else if (wordRE.test(ch)) { - stream.eatWhile(wordRE); - var word = stream.current() - if (state.lastType != ".") { - if (keywords.propertyIsEnumerable(word)) { - var kw = keywords[word] - return ret(kw.type, kw.style, word) - } - if (word == "async" && stream.match(/^\s*[\(\w]/, false)) - return ret("async", "keyword", word) - } - return ret("variable", "variable", word) - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next; - if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ - state.tokenize = tokenBase; - return ret("jsonld-keyword", "meta"); - } - while ((next = stream.next()) != null) { - if (next == quote && !escaped) break; - escaped = !escaped && next == "\\"; - } - if (!escaped) state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - function tokenQuasi(stream, state) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && next == "\\"; - } - return ret("quasi", "string-2", stream.current()); - } - - var brackets = "([{}])"; - // This is a crude lookahead trick to try and notice that we're - // parsing the argument patterns for a fat-arrow function before we - // actually hit the arrow token. It only works if the arrow is on - // the same line as the arguments and there's no strange noise - // (comments) in between. Fallback is to only notice when we hit the - // arrow, and not declare the arguments as locals for the arrow - // body. - function findFatArrow(stream, state) { - if (state.fatArrowAt) state.fatArrowAt = null; - var arrow = stream.string.indexOf("=>", stream.start); - if (arrow < 0) return; - - if (isTS) { // Try to skip TypeScript return type declarations after the arguments - var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow)) - if (m) arrow = m.index - } - - var depth = 0, sawSomething = false; - for (var pos = arrow - 1; pos >= 0; --pos) { - var ch = stream.string.charAt(pos); - var bracket = brackets.indexOf(ch); - if (bracket >= 0 && bracket < 3) { - if (!depth) { ++pos; break; } - if (--depth == 0) { if (ch == "(") sawSomething = true; break; } - } else if (bracket >= 3 && bracket < 6) { - ++depth; - } else if (wordRE.test(ch)) { - sawSomething = true; - } else if (/["'\/]/.test(ch)) { - return; - } else if (sawSomething && !depth) { - ++pos; - break; - } - } - if (sawSomething && !depth) state.fatArrowAt = pos; - } - - // Parser - - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - for (var cx = state.context; cx; cx = cx.prev) { - for (var v = cx.vars; v; v = v.next) - if (v.name == varname) return true; - } - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while(true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while(cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = {state: null, column: null, marked: null, cc: null}; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } - var state = cx.state; - cx.marked = "def"; - if (state.context) { - if (inList(state.localVars)) return; - state.localVars = {name: varname, next: state.localVars}; - } else { - if (inList(state.globalVars)) return; - if (parserConfig.globalVars) - state.globalVars = {name: varname, next: state.globalVars}; - } - } - - // Combinators - - var defaultVars = {name: "this", next: {name: "arguments"}}; - function pushcontext() { - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - cx.state.localVars = defaultVars; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function() { - var state = cx.state, indent = state.indented; - if (state.lexical.type == "stat") indent = state.lexical.indented; - else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) - indent = outer.indented; - state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - function exp(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(exp); - }; - return exp; - } - - function statement(type, value) { - if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "if") { - if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) - cx.state.cc.pop()(); - return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse); - } - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); - if (type == "variable") { - if (isTS && value == "type") { - cx.marked = "keyword" - return cont(typeexpr, expect("operator"), typeexpr, expect(";")); - } else { - return cont(pushlex("stat"), maybelabel); - } - } - if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - if (type == "class") return cont(pushlex("form"), className, poplex); - if (type == "export") return cont(pushlex("stat"), afterExport, poplex); - if (type == "import") return cont(pushlex("stat"), afterImport, poplex); - if (type == "module") return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) - if (type == "async") return cont(statement) - if (value == "@") return cont(expression, statement) - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - return expressionInner(type, false); - } - function expressionNoComma(type) { - return expressionInner(type, true); - } - function parenExpr(type) { - if (type != "(") return pass() - return cont(pushlex(")"), expression, expect(")"), poplex) - } - function expressionInner(type, noComma) { - if (cx.state.fatArrowAt == cx.stream.start) { - var body = noComma ? arrowBodyNoComma : arrowBody; - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); - else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); - } - - var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; - if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); - if (type == "function") return cont(functiondef, maybeop); - if (type == "class") return cont(pushlex("form"), classExpression, poplex); - if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression); - if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); - if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); - if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); - if (type == "{") return contCommasep(objprop, "}", null, maybeop); - if (type == "quasi") return pass(quasi, maybeop); - if (type == "new") return cont(maybeTarget(noComma)); - return cont(); - } - function maybeexpression(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expression); - } - function maybeexpressionNoComma(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expressionNoComma); - } - - function maybeoperatorComma(type, value) { - if (type == ",") return cont(expression); - return maybeoperatorNoComma(type, value, false); - } - function maybeoperatorNoComma(type, value, noComma) { - var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; - var expr = noComma == false ? expression : expressionNoComma; - if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); - if (type == "operator") { - if (/\+\+|--/.test(value)) return cont(me); - if (value == "?") return cont(expression, expect(":"), expr); - return cont(expr); - } - if (type == "quasi") { return pass(quasi, me); } - if (type == ";") return; - if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); - if (type == ".") return cont(property, me); - if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); - if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) } - } - function quasi(type, value) { - if (type != "quasi") return pass(); - if (value.slice(value.length - 2) != "${") return cont(quasi); - return cont(expression, continueQuasi); - } - function continueQuasi(type) { - if (type == "}") { - cx.marked = "string-2"; - cx.state.tokenize = tokenQuasi; - return cont(quasi); - } - } - function arrowBody(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expression); - } - function arrowBodyNoComma(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expressionNoComma); - } - function maybeTarget(noComma) { - return function(type) { - if (type == ".") return cont(noComma ? targetNoComma : target); - else return pass(noComma ? expressionNoComma : expression); - }; - } - function target(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } - } - function targetNoComma(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperatorComma, expect(";"), poplex); - } - function property(type) { - if (type == "variable") {cx.marked = "property"; return cont();} - } - function objprop(type, value) { - if (type == "async") { - cx.marked = "property"; - return cont(objprop); - } else if (type == "variable" || cx.style == "keyword") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(getterSetter); - return cont(afterprop); - } else if (type == "number" || type == "string") { - cx.marked = jsonldMode ? "property" : (cx.style + " property"); - return cont(afterprop); - } else if (type == "jsonld-keyword") { - return cont(afterprop); - } else if (type == "modifier") { - return cont(objprop) - } else if (type == "[") { - return cont(expression, expect("]"), afterprop); - } else if (type == "spread") { - return cont(expression, afterprop); - } else if (type == ":") { - return pass(afterprop) - } - } - function getterSetter(type) { - if (type != "variable") return pass(afterprop); - cx.marked = "property"; - return cont(functiondef); - } - function afterprop(type) { - if (type == ":") return cont(expressionNoComma); - if (type == "(") return pass(functiondef); - } - function commasep(what, end, sep) { - function proceed(type, value) { - if (sep ? sep.indexOf(type) > -1 : type == ",") { - var lex = cx.state.lexical; - if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; - return cont(function(type, value) { - if (type == end || value == end) return pass() - return pass(what) - }, proceed); - } - if (type == end || value == end) return cont(); - return cont(expect(end)); - } - return function(type, value) { - if (type == end || value == end) return cont(); - return pass(what, proceed); - }; - } - function contCommasep(what, end, info) { - for (var i = 3; i < arguments.length; i++) - cx.cc.push(arguments[i]); - return cont(pushlex(end, info), commasep(what, end), poplex); - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function maybetype(type, value) { - if (isTS) { - if (type == ":") return cont(typeexpr); - if (value == "?") return cont(maybetype); - } - } - function typeexpr(type) { - if (type == "variable") {cx.marked = "type"; return cont(afterType);} - if (type == "string" || type == "number" || type == "atom") return cont(afterType); - if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType) - if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) - } - function maybeReturnType(type) { - if (type == "=>") return cont(typeexpr) - } - function typeprop(type, value) { - if (type == "variable" || cx.style == "keyword") { - cx.marked = "property" - return cont(typeprop) - } else if (value == "?") { - return cont(typeprop) - } else if (type == ":") { - return cont(typeexpr) - } else if (type == "[") { - return cont(expression, maybetype, expect("]"), typeprop) - } - } - function typearg(type) { - if (type == "variable") return cont(typearg) - else if (type == ":") return cont(typeexpr) - } - function afterType(type, value) { - if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) - if (value == "|" || type == ".") return cont(typeexpr) - if (type == "[") return cont(expect("]"), afterType) - if (value == "extends") return cont(typeexpr) - } - function vardef() { - return pass(pattern, maybetype, maybeAssign, vardefCont); - } - function pattern(type, value) { - if (type == "modifier") return cont(pattern) - if (type == "variable") { register(value); return cont(); } - if (type == "spread") return cont(pattern); - if (type == "[") return contCommasep(pattern, "]"); - if (type == "{") return contCommasep(proppattern, "}"); - } - function proppattern(type, value) { - if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { - register(value); - return cont(maybeAssign); - } - if (type == "variable") cx.marked = "property"; - if (type == "spread") return cont(pattern); - if (type == "}") return pass(); - return cont(expect(":"), pattern, maybeAssign); - } - function maybeAssign(_type, value) { - if (value == "=") return cont(expressionNoComma); - } - function vardefCont(type) { - if (type == ",") return cont(vardef); - } - function maybeelse(type, value) { - if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); - } - function forspec(type) { - if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); - } - function forspec1(type) { - if (type == "var") return cont(vardef, expect(";"), forspec2); - if (type == ";") return cont(forspec2); - if (type == "variable") return cont(formaybeinof); - return pass(expression, expect(";"), forspec2); - } - function formaybeinof(_type, value) { - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return cont(maybeoperatorComma, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return pass(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} - if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); - if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef) - } - function funarg(type) { - if (type == "spread") return cont(funarg); - return pass(pattern, maybetype, maybeAssign); - } - function classExpression(type, value) { - // Class expressions may have an optional name. - if (type == "variable") return className(type, value); - return classNameAfter(type, value); - } - function className(type, value) { - if (type == "variable") {register(value); return cont(classNameAfter);} - } - function classNameAfter(type, value) { - if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, classNameAfter) - if (value == "extends" || value == "implements" || (isTS && type == ",")) - return cont(isTS ? typeexpr : expression, classNameAfter); - if (type == "{") return cont(pushlex("}"), classBody, poplex); - } - function classBody(type, value) { - if (type == "variable" || cx.style == "keyword") { - if ((value == "async" || value == "static" || value == "get" || value == "set" || - (isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) && - cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) { - cx.marked = "keyword"; - return cont(classBody); - } - cx.marked = "property"; - return cont(isTS ? classfield : functiondef, classBody); - } - if (type == "[") - return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody) - if (value == "*") { - cx.marked = "keyword"; - return cont(classBody); - } - if (type == ";") return cont(classBody); - if (type == "}") return cont(); - if (value == "@") return cont(expression, classBody) - } - function classfield(type, value) { - if (value == "?") return cont(classfield) - if (type == ":") return cont(typeexpr, maybeAssign) - if (value == "=") return cont(expressionNoComma) - return pass(functiondef) - } - function afterExport(type, value) { - if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } - if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } - if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";")); - return pass(statement); - } - function exportField(type, value) { - if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); } - if (type == "variable") return pass(expressionNoComma, exportField); - } - function afterImport(type) { - if (type == "string") return cont(); - return pass(importSpec, maybeMoreImports, maybeFrom); - } - function importSpec(type, value) { - if (type == "{") return contCommasep(importSpec, "}"); - if (type == "variable") register(value); - if (value == "*") cx.marked = "keyword"; - return cont(maybeAs); - } - function maybeMoreImports(type) { - if (type == ",") return cont(importSpec, maybeMoreImports) - } - function maybeAs(_type, value) { - if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } - } - function maybeFrom(_type, value) { - if (value == "from") { cx.marked = "keyword"; return cont(expression); } - } - function arrayLiteral(type) { - if (type == "]") return cont(); - return pass(commasep(expressionNoComma, "]")); - } - - function isContinuedStatement(state, textAfter) { - return state.lastType == "operator" || state.lastType == "," || - isOperatorChar.test(textAfter.charAt(0)) || - /[,.]/.test(textAfter.charAt(0)); - } - - // Interface - - return { - startState: function(basecolumn) { - var state = { - tokenize: tokenBase, - lastType: "sof", - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: parserConfig.localVars, - context: parserConfig.localVars && {vars: parserConfig.localVars}, - indented: basecolumn || 0 - }; - if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") - state.globalVars = parserConfig.globalVars; - return state; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - findFatArrow(stream, state); - } - if (state.tokenize != tokenComment && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; - return parseJS(state, style, type, content, stream); - }, - - indent: function(state, textAfter) { - if (state.tokenize == tokenComment) return CodeMirror.Pass; - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top - // Kludge to prevent 'maybelse' from blocking lexical scope pops - if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { - var c = state.cc[i]; - if (c == poplex) lexical = lexical.prev; - else if (c != maybeelse) break; - } - while ((lexical.type == "stat" || lexical.type == "form") && - (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) && - (top == maybeoperatorComma || top == maybeoperatorNoComma) && - !/^[,\.=+\-*:?[\(]/.test(textAfter)))) - lexical = lexical.prev; - if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") - lexical = lexical.prev; - var type = lexical.type, closing = firstChar == type; - - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "form") return lexical.indented + indentUnit; - else if (type == "stat") - return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); - else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, - blockCommentStart: jsonMode ? null : "/*", - blockCommentEnd: jsonMode ? null : "*/", - lineComment: jsonMode ? null : "//", - fold: "brace", - closeBrackets: "()[]{}''\"\"``", - - helperType: jsonMode ? "json" : "javascript", - jsonldMode: jsonldMode, - jsonMode: jsonMode, - - expressionAllowed: expressionAllowed, - skipExpression: function(state) { - var top = state.cc[state.cc.length - 1] - if (top == expression || top == expressionNoComma) state.cc.pop() - } - }; -}); - -CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); - -CodeMirror.defineMIME("text/javascript", "javascript"); -CodeMirror.defineMIME("text/ecmascript", "javascript"); -CodeMirror.defineMIME("application/javascript", "javascript"); -CodeMirror.defineMIME("application/x-javascript", "javascript"); -CodeMirror.defineMIME("application/ecmascript", "javascript"); -CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); -CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); -CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); - -}); diff --git a/js/DevHelper/Lib/CodeMirror/mode/javascript/json-ld.html b/js/DevHelper/Lib/CodeMirror/mode/javascript/json-ld.html deleted file mode 100644 index 3a37f0b..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/javascript/json-ld.html +++ /dev/null @@ -1,72 +0,0 @@ - - -CodeMirror: JSON-LD mode - - - - - - - - - - - - -
-

JSON-LD mode

- - -
- - - -

This is a specialization of the JavaScript mode.

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/javascript/test.js b/js/DevHelper/Lib/CodeMirror/mode/javascript/test.js deleted file mode 100644 index 328cbc2..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/javascript/test.js +++ /dev/null @@ -1,379 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT("locals", - "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }"); - - MT("comma-and-binop", - "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }"); - - MT("destructuring", - "([keyword function]([def a], [[[def b], [def c] ]]) {", - " [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);", - " [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];", - "})();"); - - MT("destructure_trailing_comma", - "[keyword let] {[def a], [def b],} [operator =] [variable foo];", - "[keyword let] [def c];"); // Parser still in good state? - - MT("class_body", - "[keyword class] [def Foo] {", - " [property constructor]() {}", - " [property sayName]() {", - " [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];", - " }", - "}"); - - MT("class", - "[keyword class] [def Point] [keyword extends] [variable SuperThing] {", - " [keyword get] [property prop]() { [keyword return] [number 24]; }", - " [property constructor]([def x], [def y]) {", - " [keyword super]([string 'something']);", - " [keyword this].[property x] [operator =] [variable-2 x];", - " }", - "}"); - - MT("anonymous_class_expression", - "[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {", - " [property add]([def a], [def b]) {}", - "};"); - - MT("named_class_expression", - "[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {", - " [property sub]([def a], [def b]) {}", - "};"); - - MT("class_async_method", - "[keyword class] [def Foo] {", - " [property sayName1]() {}", - " [keyword async] [property sayName2]() {}", - "}"); - - MT("import", - "[keyword function] [def foo]() {", - " [keyword import] [def $] [keyword from] [string 'jquery'];", - " [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];", - "}"); - - MT("import_trailing_comma", - "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") - - MT("const", - "[keyword function] [def f]() {", - " [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", - "}"); - - MT("for/of", - "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); - - MT("generator", - "[keyword function*] [def repeat]([def n]) {", - " [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])", - " [keyword yield] [variable-2 i];", - "}"); - - MT("quotedStringAddition", - "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); - - MT("quotedFatArrow", - "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];"); - - MT("fatArrow", - "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);", - "[variable a];", // No longer in scope - "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];", - "[variable c];"); - - MT("spread", - "[keyword function] [def f]([def a], [meta ...][def b]) {", - " [variable something]([variable-2 a], [meta ...][variable-2 b]);", - "}"); - - MT("quasi", - "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); - - MT("quasi_no_function", - "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]"); - - MT("indent_statement", - "[keyword var] [def x] [operator =] [number 10]", - "[variable x] [operator +=] [variable y] [operator +]", - " [atom Infinity]", - "[keyword debugger];"); - - MT("indent_if", - "[keyword if] ([number 1])", - " [keyword break];", - "[keyword else] [keyword if] ([number 2])", - " [keyword continue];", - "[keyword else]", - " [number 10];", - "[keyword if] ([number 1]) {", - " [keyword break];", - "} [keyword else] [keyword if] ([number 2]) {", - " [keyword continue];", - "} [keyword else] {", - " [number 10];", - "}"); - - MT("indent_for", - "[keyword for] ([keyword var] [def i] [operator =] [number 0];", - " [variable i] [operator <] [number 100];", - " [variable i][operator ++])", - " [variable doSomething]([variable i]);", - "[keyword debugger];"); - - MT("indent_c_style", - "[keyword function] [def foo]()", - "{", - " [keyword debugger];", - "}"); - - MT("indent_else", - "[keyword for] (;;)", - " [keyword if] ([variable foo])", - " [keyword if] ([variable bar])", - " [number 1];", - " [keyword else]", - " [number 2];", - " [keyword else]", - " [number 3];"); - - MT("indent_funarg", - "[variable foo]([number 10000],", - " [keyword function]([def a]) {", - " [keyword debugger];", - "};"); - - MT("indent_below_if", - "[keyword for] (;;)", - " [keyword if] ([variable foo])", - " [number 1];", - "[number 2];"); - - MT("indent_semicolonless_if", - "[keyword function] [def foo]() {", - " [keyword if] ([variable x])", - " [variable foo]()", - "}") - - MT("indent_semicolonless_if_with_statement", - "[keyword function] [def foo]() {", - " [keyword if] ([variable x])", - " [variable foo]()", - " [variable bar]()", - "}") - - MT("multilinestring", - "[keyword var] [def x] [operator =] [string 'foo\\]", - "[string bar'];"); - - MT("scary_regexp", - "[string-2 /foo[[/]]bar/];"); - - MT("indent_strange_array", - "[keyword var] [def x] [operator =] [[", - " [number 1],,", - " [number 2],", - "]];", - "[number 10];"); - - MT("param_default", - "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {", - " [keyword return] [variable-2 x];", - "}"); - - MT("new_target", - "[keyword function] [def F]([def target]) {", - " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", - " [keyword return] [keyword new]", - " .[keyword target];", - " }", - "}"); - - MT("async", - "[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }"); - - MT("async_assignment", - "[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };"); - - MT("async_object", - "[keyword let] [def obj] [operator =] { [property async]: [atom false] };"); - - // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173 - MT("async_object_function", - "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };"); - - MT("async_object_properties", - "[keyword let] [def obj] [operator =] {", - " [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", - " [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },", - " [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },", - "};"); - - MT("async_arrow", - "[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };"); - - MT("async_jquery", - "[variable $].[property ajax]({", - " [property url]: [variable url],", - " [property async]: [atom true],", - " [property method]: [string 'GET']", - "});"); - - MT("async_variable", - "[keyword const] [def async] [operator =] {[property a]: [number 1]};", - "[keyword const] [def foo] [operator =] [string-2 `bar ${][variable async].[property a][string-2 }`];") - - MT("indent_switch", - "[keyword switch] ([variable x]) {", - " [keyword default]:", - " [keyword return] [number 2]", - "}") - - var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript") - function TS(name) { - test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) - } - - TS("typescript_extend_type", - "[keyword class] [def Foo] [keyword extends] [type Some][operator <][type Type][operator >] {}") - - TS("typescript_arrow_type", - "[keyword let] [def x]: ([variable arg]: [type Type]) [operator =>] [type ReturnType]") - - TS("typescript_class", - "[keyword class] [def Foo] {", - " [keyword public] [keyword static] [property main]() {}", - " [keyword private] [property _foo]: [type string];", - "}") - - TS("typescript_literal_types", - "[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];", - "[keyword interface] [def MyAttributes] {", - " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", - " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", - "}", - "[keyword interface] [def MyInstance] [keyword extends] [type Sequelize].[type Instance] [operator <] [type MyAttributes] [operator >] {", - " [property rawAttributes]: [type MyAttributes];", - " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", - " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", - "}") - - TS("typescript_extend_operators", - "[keyword export] [keyword interface] [def UserModel] [keyword extends]", - " [type Sequelize].[type Model] [operator <] [type UserInstance], [type UserAttributes] [operator >] {", - " [property findById]: (", - " [variable userId]: [type number]", - " ) [operator =>] [type Promise] [operator <] [type Array] [operator <] { [property id], [property name] } [operator >>];", - " [property updateById]: (", - " [variable userId]: [type number],", - " [variable isActive]: [type boolean]", - " ) [operator =>] [type Promise] [operator <] [type AccountHolderNotificationPreferenceInstance] [operator >];", - " }") - - TS("typescript_interface_with_const", - "[keyword const] [def hello]: {", - " [property prop1][operator ?]: [type string];", - " [property prop2][operator ?]: [type string];", - "} [operator =] {};") - - TS("typescript_double_extend", - "[keyword export] [keyword interface] [def UserAttributes] {", - " [property id][operator ?]: [type number];", - " [property createdAt][operator ?]: [type Date];", - "}", - "[keyword export] [keyword interface] [def UserInstance] [keyword extends] [type Sequelize].[type Instance][operator <][type UserAttributes][operator >], [type UserAttributes] {", - " [property id]: [type number];", - " [property createdAt]: [type Date];", - "}"); - - TS("typescript_index_signature", - "[keyword interface] [def A] {", - " [[ [variable prop]: [type string] ]]: [type any];", - " [property prop1]: [type any];", - "}"); - - TS("typescript_generic_class", - "[keyword class] [def Foo][operator <][type T][operator >] {", - " [property bar]() {}", - " [property foo](): [type Foo] {}", - "}") - - TS("typescript_type_when_keyword", - "[keyword export] [keyword type] [type AB] [operator =] [type A] [operator |] [type B];", - "[keyword type] [type Flags] [operator =] {", - " [property p1]: [type string];", - " [property p2]: [type boolean];", - "};") - - TS("typescript_type_when_not_keyword", - "[keyword class] [def HasType] {", - " [property type]: [type string];", - " [property constructor]([def type]: [type string]) {", - " [keyword this].[property type] [operator =] [variable-2 type];", - " }", - " [property setType]({ [def type] }: { [property type]: [type string]; }) {", - " [keyword this].[property type] [operator =] [variable-2 type];", - " }", - "}") - - TS("typescript_function_generics", - "[keyword function] [def a]() {}", - "[keyword function] [def b][operator <][type IA] [keyword extends] [type object], [type IB] [keyword extends] [type object][operator >]() {}", - "[keyword function] [def c]() {}") - - TS("typescript_complex_return_type", - "[keyword function] [def A]() {", - " [keyword return] [keyword this].[property property];", - "}", - "[keyword function] [def B](): [type Promise][operator <]{ [[ [variable key]: [type string] ]]: [type any] } [operator |] [atom null][operator >] {", - " [keyword return] [keyword this].[property property];", - "}") - - TS("typescript_complex_type_casting", - "[keyword const] [def giftpay] [operator =] [variable config].[property get]([string 'giftpay']) [keyword as] { [[ [variable platformUuid]: [type string] ]]: { [property version]: [type number]; [property apiCode]: [type string]; } };") - - var jsonld_mode = CodeMirror.getMode( - {indentUnit: 2}, - {name: "javascript", jsonld: true} - ); - function LD(name) { - test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1)); - } - - LD("json_ld_keywords", - '{', - ' [meta "@context"]: {', - ' [meta "@base"]: [string "http://example.com"],', - ' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],', - ' [property "likesFlavor"]: {', - ' [meta "@container"]: [meta "@list"]', - ' [meta "@reverse"]: [string "@beFavoriteOf"]', - ' },', - ' [property "nick"]: { [meta "@container"]: [meta "@set"] },', - ' [property "nick"]: { [meta "@container"]: [meta "@index"] }', - ' },', - ' [meta "@graph"]: [[ {', - ' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],', - ' [property "name"]: [string "John Lennon"],', - ' [property "modified"]: {', - ' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],', - ' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]', - ' }', - ' } ]]', - '}'); - - LD("json_ld_fake", - '{', - ' [property "@fake"]: [string "@fake"],', - ' [property "@contextual"]: [string "@identifier"],', - ' [property "user@domain.com"]: [string "@graphical"],', - ' [property "@ID"]: [string "@@ID"]', - '}'); -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/javascript/typescript.html b/js/DevHelper/Lib/CodeMirror/mode/javascript/typescript.html deleted file mode 100644 index 1f26d7f..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/javascript/typescript.html +++ /dev/null @@ -1,61 +0,0 @@ - - -CodeMirror: TypeScript mode - - - - - - - - - -
-

TypeScript mode

- - -
- - - -

This is a specialization of the JavaScript mode.

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/xml/index.html b/js/DevHelper/Lib/CodeMirror/mode/xml/index.html deleted file mode 100644 index c56b8b6..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/xml/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - -CodeMirror: XML mode - - - - - - - - - -
-

XML mode

-
- -

The XML mode supports these configuration parameters:

-
-
htmlMode (boolean)
-
This switches the mode to parse HTML instead of XML. This - means attributes do not have to be quoted, and some elements - (such as br) do not require a closing tag.
-
matchClosing (boolean)
-
Controls whether the mode checks that close tags match the - corresponding opening tag, and highlights mismatches as errors. - Defaults to true.
-
alignCDATA (boolean)
-
Setting this to true will force the opening tag of CDATA - blocks to not be indented.
-
- -

MIME types defined: application/xml, text/html.

-
diff --git a/js/DevHelper/Lib/CodeMirror/mode/xml/test.js b/js/DevHelper/Lib/CodeMirror/mode/xml/test.js deleted file mode 100644 index f48156b..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/xml/test.js +++ /dev/null @@ -1,51 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml"; - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); } - - MT("matching", - "[tag&bracket <][tag top][tag&bracket >]", - " text", - " [tag&bracket <][tag inner][tag&bracket />]", - "[tag&bracket ]"); - - MT("nonmatching", - "[tag&bracket <][tag top][tag&bracket >]", - " [tag&bracket <][tag inner][tag&bracket />]", - " [tag&bracket ]"); - - MT("doctype", - "[meta ]", - "[tag&bracket <][tag top][tag&bracket />]"); - - MT("cdata", - "[tag&bracket <][tag top][tag&bracket >]", - " [atom ]", - "[tag&bracket ]"); - - // HTML tests - mode = CodeMirror.getMode({indentUnit: 2}, "text/html"); - - MT("selfclose", - "[tag&bracket <][tag html][tag&bracket >]", - " [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]", - "[tag&bracket ]"); - - MT("list", - "[tag&bracket <][tag ol][tag&bracket >]", - " [tag&bracket <][tag li][tag&bracket >]one", - " [tag&bracket <][tag li][tag&bracket >]two", - "[tag&bracket ]"); - - MT("valueless", - "[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]"); - - MT("pThenArticle", - "[tag&bracket <][tag p][tag&bracket >]", - " foo", - "[tag&bracket <][tag article][tag&bracket >]bar"); - -})(); diff --git a/js/DevHelper/Lib/CodeMirror/mode/xml/xml.js b/js/DevHelper/Lib/CodeMirror/mode/xml/xml.js deleted file mode 100644 index f987a3a..0000000 --- a/js/DevHelper/Lib/CodeMirror/mode/xml/xml.js +++ /dev/null @@ -1,394 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -var htmlConfig = { - autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, - 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, - 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, - 'track': true, 'wbr': true, 'menuitem': true}, - implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, - 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, - 'th': true, 'tr': true}, - contextGrabbers: { - 'dd': {'dd': true, 'dt': true}, - 'dt': {'dd': true, 'dt': true}, - 'li': {'li': true}, - 'option': {'option': true, 'optgroup': true}, - 'optgroup': {'optgroup': true}, - 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, - 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, - 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, - 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, - 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, - 'rp': {'rp': true, 'rt': true}, - 'rt': {'rp': true, 'rt': true}, - 'tbody': {'tbody': true, 'tfoot': true}, - 'td': {'td': true, 'th': true}, - 'tfoot': {'tbody': true}, - 'th': {'td': true, 'th': true}, - 'thead': {'tbody': true, 'tfoot': true}, - 'tr': {'tr': true} - }, - doNotIndent: {"pre": true}, - allowUnquoted: true, - allowMissing: true, - caseFold: true -} - -var xmlConfig = { - autoSelfClosers: {}, - implicitlyClosed: {}, - contextGrabbers: {}, - doNotIndent: {}, - allowUnquoted: false, - allowMissing: false, - caseFold: false -} - -CodeMirror.defineMode("xml", function(editorConf, config_) { - var indentUnit = editorConf.indentUnit - var config = {} - var defaults = config_.htmlMode ? htmlConfig : xmlConfig - for (var prop in defaults) config[prop] = defaults[prop] - for (var prop in config_) config[prop] = config_[prop] - - // Return variables for tokenizers - var type, setStyle; - - function inText(stream, state) { - function chain(parser) { - state.tokenize = parser; - return parser(stream, state); - } - - var ch = stream.next(); - if (ch == "<") { - if (stream.eat("!")) { - if (stream.eat("[")) { - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); - else return null; - } else if (stream.match("--")) { - return chain(inBlock("comment", "-->")); - } else if (stream.match("DOCTYPE", true, true)) { - stream.eatWhile(/[\w\._\-]/); - return chain(doctype(1)); - } else { - return null; - } - } else if (stream.eat("?")) { - stream.eatWhile(/[\w\._\-]/); - state.tokenize = inBlock("meta", "?>"); - return "meta"; - } else { - type = stream.eat("/") ? "closeTag" : "openTag"; - state.tokenize = inTag; - return "tag bracket"; - } - } else if (ch == "&") { - var ok; - if (stream.eat("#")) { - if (stream.eat("x")) { - ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); - } else { - ok = stream.eatWhile(/[\d]/) && stream.eat(";"); - } - } else { - ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); - } - return ok ? "atom" : "error"; - } else { - stream.eatWhile(/[^&<]/); - return null; - } - } - inText.isInText = true; - - function inTag(stream, state) { - var ch = stream.next(); - if (ch == ">" || (ch == "/" && stream.eat(">"))) { - state.tokenize = inText; - type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag bracket"; - } else if (ch == "=") { - type = "equals"; - return null; - } else if (ch == "<") { - state.tokenize = inText; - state.state = baseState; - state.tagName = state.tagStart = null; - var next = state.tokenize(stream, state); - return next ? next + " tag error" : "tag error"; - } else if (/[\'\"]/.test(ch)) { - state.tokenize = inAttribute(ch); - state.stringStartCol = stream.column(); - return state.tokenize(stream, state); - } else { - stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); - return "word"; - } - } - - function inAttribute(quote) { - var closure = function(stream, state) { - while (!stream.eol()) { - if (stream.next() == quote) { - state.tokenize = inTag; - break; - } - } - return "string"; - }; - closure.isInAttribute = true; - return closure; - } - - function inBlock(style, terminator) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - state.tokenize = inText; - break; - } - stream.next(); - } - return style; - }; - } - function doctype(depth) { - return function(stream, state) { - var ch; - while ((ch = stream.next()) != null) { - if (ch == "<") { - state.tokenize = doctype(depth + 1); - return state.tokenize(stream, state); - } else if (ch == ">") { - if (depth == 1) { - state.tokenize = inText; - break; - } else { - state.tokenize = doctype(depth - 1); - return state.tokenize(stream, state); - } - } - } - return "meta"; - }; - } - - function Context(state, tagName, startOfLine) { - this.prev = state.context; - this.tagName = tagName; - this.indent = state.indented; - this.startOfLine = startOfLine; - if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) - this.noIndent = true; - } - function popContext(state) { - if (state.context) state.context = state.context.prev; - } - function maybePopContext(state, nextTagName) { - var parentTagName; - while (true) { - if (!state.context) { - return; - } - parentTagName = state.context.tagName; - if (!config.contextGrabbers.hasOwnProperty(parentTagName) || - !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { - return; - } - popContext(state); - } - } - - function baseState(type, stream, state) { - if (type == "openTag") { - state.tagStart = stream.column(); - return tagNameState; - } else if (type == "closeTag") { - return closeTagNameState; - } else { - return baseState; - } - } - function tagNameState(type, stream, state) { - if (type == "word") { - state.tagName = stream.current(); - setStyle = "tag"; - return attrState; - } else { - setStyle = "error"; - return tagNameState; - } - } - function closeTagNameState(type, stream, state) { - if (type == "word") { - var tagName = stream.current(); - if (state.context && state.context.tagName != tagName && - config.implicitlyClosed.hasOwnProperty(state.context.tagName)) - popContext(state); - if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { - setStyle = "tag"; - return closeState; - } else { - setStyle = "tag error"; - return closeStateErr; - } - } else { - setStyle = "error"; - return closeStateErr; - } - } - - function closeState(type, _stream, state) { - if (type != "endTag") { - setStyle = "error"; - return closeState; - } - popContext(state); - return baseState; - } - function closeStateErr(type, stream, state) { - setStyle = "error"; - return closeState(type, stream, state); - } - - function attrState(type, _stream, state) { - if (type == "word") { - setStyle = "attribute"; - return attrEqState; - } else if (type == "endTag" || type == "selfcloseTag") { - var tagName = state.tagName, tagStart = state.tagStart; - state.tagName = state.tagStart = null; - if (type == "selfcloseTag" || - config.autoSelfClosers.hasOwnProperty(tagName)) { - maybePopContext(state, tagName); - } else { - maybePopContext(state, tagName); - state.context = new Context(state, tagName, tagStart == state.indented); - } - return baseState; - } - setStyle = "error"; - return attrState; - } - function attrEqState(type, stream, state) { - if (type == "equals") return attrValueState; - if (!config.allowMissing) setStyle = "error"; - return attrState(type, stream, state); - } - function attrValueState(type, stream, state) { - if (type == "string") return attrContinuedState; - if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;} - setStyle = "error"; - return attrState(type, stream, state); - } - function attrContinuedState(type, stream, state) { - if (type == "string") return attrContinuedState; - return attrState(type, stream, state); - } - - return { - startState: function(baseIndent) { - var state = {tokenize: inText, - state: baseState, - indented: baseIndent || 0, - tagName: null, tagStart: null, - context: null} - if (baseIndent != null) state.baseIndent = baseIndent - return state - }, - - token: function(stream, state) { - if (!state.tagName && stream.sol()) - state.indented = stream.indentation(); - - if (stream.eatSpace()) return null; - type = null; - var style = state.tokenize(stream, state); - if ((style || type) && style != "comment") { - setStyle = null; - state.state = state.state(type || style, stream, state); - if (setStyle) - style = setStyle == "error" ? style + " error" : setStyle; - } - return style; - }, - - indent: function(state, textAfter, fullLine) { - var context = state.context; - // Indent multi-line strings (e.g. css). - if (state.tokenize.isInAttribute) { - if (state.tagStart == state.indented) - return state.stringStartCol + 1; - else - return state.indented + indentUnit; - } - if (context && context.noIndent) return CodeMirror.Pass; - if (state.tokenize != inTag && state.tokenize != inText) - return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; - // Indent the starts of attribute names. - if (state.tagName) { - if (config.multilineTagIndentPastTag !== false) - return state.tagStart + state.tagName.length + 2; - else - return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1); - } - if (config.alignCDATA && /$/, - blockCommentStart: "", - - configuration: config.htmlMode ? "html" : "xml", - helperType: config.htmlMode ? "html" : "xml", - - skipAttribute: function(state) { - if (state.state == attrValueState) - state.state = attrState - } - }; -}); - -CodeMirror.defineMIME("text/xml", "xml"); -CodeMirror.defineMIME("application/xml", "xml"); -if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) - CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); - -}); diff --git a/js/DevHelper/full/template_edit.js b/js/DevHelper/full/template_edit.js deleted file mode 100755 index 64f19a4..0000000 --- a/js/DevHelper/full/template_edit.js +++ /dev/null @@ -1,132 +0,0 @@ -/** @param {jQuery} $ jQuery Object */ -!function ($) { - - var defaultExtraKeys = {}; - defaultExtraKeys['Tab'] = 'indentMore'; - defaultExtraKeys['Shift-Tab'] = 'indentLess'; - - var defaultConfig = { - mode: 'htmlmixed', - lineNumbers: 1, - indentWithTabs: 1, - smartIndent: 1, - tabSize: 4, - indentUnit: 4, - extraKeys: defaultExtraKeys - }; - - if (XenForo.TemplateEditor) { - var targetPrototype = XenForo.TemplateEditor.prototype; - - targetPrototype.DevHelper_extraKeysSave = function () { - $('#saveReloadButton').trigger('click'); - }; - - targetPrototype.DevHelper_setupCM = function (editor) { - var $textarea = editor.$textarea; - var $textareaWrapper = this.getTextareaWrapper(); - - // default to use the mixed HTML mode - var cmMode = 'htmlmixed'; - if (editor.$title.val().indexOf('.css') !== -1) { - // we are editing a CSS template - // switch to CSS mode - cmMode = 'css'; - } - - var config = defaultConfig; - config['value'] = $textarea.val(); - config['mode'] = cmMode; - - config.extraKeys['Cmd-S'] = $.context(this, 'DevHelper_extraKeysSave'); - config.extraKeys['Ctrl-S'] = $.context(this, 'DevHelper_extraKeysSave'); - - var theCM = CodeMirror(function () { - }, config); - theCM.on('change', function (cm) { - $textarea.val(cm.getValue()); - }); - - var $wrapper = $(theCM.getWrapperElement()); - $wrapper.width($textareaWrapper.parent().width()); - - // append the CodeMirror editor's wrapper to the page - $textareaWrapper.append($wrapper); - theCM.refresh(); - - // hide the textarea - $textarea.xfHide(); - - // save it for later access - editor.theCM = theCM; - editor.$theCMWrapper = $wrapper; - }; - - var originalInitializePrimaryEditor = targetPrototype.initializePrimaryEditor; - targetPrototype.initializePrimaryEditor = function () { - originalInitializePrimaryEditor.call(this); - - var templateTitle = this.$titleOriginal.strval(); - var editor = this.editors[templateTitle]; - - this.DevHelper_setupCM(editor); - }; - - var originalCreateEditor = targetPrototype.createEditor; - targetPrototype.createEditor = function (templateTitle, $prevTab) { - var editor = originalCreateEditor.call(this, templateTitle, $prevTab); - - this.DevHelper_setupCM(editor); - - // immediately hide the editor - editor.$theCMWrapper.xfHide(); - - return editor; - }; - - targetPrototype.switchEditor = function (e) { - var $target = $(e.target).closest('a'), - editor; - - // switch the active tab - $target.closest('li') - .addClass('active') - .siblings().removeClass('active'); - - // hide all CodeMirror instances - $('.CodeMirror', this.getTextareaWrapper()).xfHide(); - - editor = this.editors[$target.attr('templateTitle')]; - - // display the only needed one - editor.$theCMWrapper.xfShow(); - - return false; - }; - } - - XenForo.DevHelper_CodeMirror_TextArea = function ($textarea) { - $textarea.each(function () { - var config = defaultConfig; - - //config['viewportMargin'] = 'Infinity'; - - var functionSave = function () { - $textarea.parents('form').find('input.button.primary').trigger('click'); - }; - config.extraKeys['Cmd-S'] = functionSave; - config.extraKeys['Ctrl-S'] = functionSave; - - var theCM = CodeMirror.fromTextArea(this, defaultConfig); - - theCM.on('change', function (cm) { - $textarea.val(cm.getValue()); - }); - $(theCM.getWrapperElement()).addClass('DevHelper_CodeMirror_TextArea'); - }); - }; - - // support template modification `find` textarea - XenForo.register('textarea#ctrl_find.code', 'XenForo.DevHelper_CodeMirror_TextArea'); - XenForo.register('textarea#ctrl_replace.code', 'XenForo.DevHelper_CodeMirror_TextArea'); -}(jQuery); \ No newline at end of file diff --git a/library/DevHelper/Autoloader.php b/library/DevHelper/Autoloader.php deleted file mode 100644 index fd5f4fb..0000000 --- a/library/DevHelper/Autoloader.php +++ /dev/null @@ -1,175 +0,0 @@ -_setup) { - return; - } - - $this->_rootDir = $rootDir; - spl_autoload_register(array($this, 'autoload')); - - $this->_setup = true; - } - - public function autoload($class) - { - if (class_exists($class, false) || interface_exists($class, false)) { - return true; - } - - if ($class == 'utf8_entity_decoder') { - return false; - } - - if (substr($class, 0, 5) == 'XFCP_') { - return false; - } - - $filename = $this->autoloaderClassToFile($class); - if (!$filename) { - return false; - } - - if (file_exists($filename)) { - /** @noinspection PhpIncludeInspection */ - require($filename); - if (class_exists($class, false) || interface_exists($class, false)) { - return true; - } - } - - return false; - } - - public static function throwIfNotSetup() - { - if (empty($_SERVER['SCRIPT_FILENAME'])) { - throw new XenForo_Exception('Cannot get value for $_SERVER[\'SCRIPT_FILENAME\']'); - } - - /** @var XenForo_Application $app */ - $app = XenForo_Application::getInstance(); - $root = $app->getRootDir(); - $candidates = array( - file_get_contents($root . '/index.php'), - file_get_contents($root . '/admin.php'), - ); - - if (empty($_SERVER['DEVHELPER_ROUTER_PHP']) - && in_array(file_get_contents($_SERVER['SCRIPT_FILENAME']), $candidates, true) - && !self::$_instance - ) { - throw new XenForo_Exception('DevHelper_Autoloader must be setup'); - } - - if (!class_exists('DevHelper_XenForo_Autoloader')) { - eval('class DevHelper_XenForo_Autoloader extends XenForo_Autoloader { - public static function setInstanceCarelessly($loader = null) - { - self::$_instance = $loader; - } - }'); - } - - /** @noinspection PhpUndefinedClassInspection */ - DevHelper_XenForo_Autoloader::setInstanceCarelessly(self::$_instance); - } - - final public static function getDevHelperInstance() - { - if (!self::$_instance) { - self::$_instance = new self(); - } - - return self::$_instance; - } - - public function autoloaderClassToFile($class) - { - static $classes = array( - 'XenForo_CodeEvent', - 'XenForo_Debug', - 'XenForo_Template_Abstract', - 'XenForo_ViewRenderer_Json', - ); - if (in_array($class, $classes, true)) { - $class = 'DevHelper_' . $class; - } - - $classFile = $this->_autoloaderClassToFile($class); - $classFile = $this->_locateClassFile($classFile); - - $strPos = 0; - if (substr($class, 0, 9) !== 'DevHelper') { - $strPos = strpos($class, 'ShippableHelper_'); - } - if ($strPos > 0) { - // a helper class is being called, check its version vs. ours - $classVersionId = 0; - if (file_exists($classFile)) { - $classContents = file_get_contents($classFile); - - $classVersionId = DevHelper_Helper_ShippableHelper::getVersionId($class, $classFile, $classContents); - if ($classVersionId === false) { - die('Add-on class version could not be detected: ' . $classFile); - } - } - - $oursClass = 'DevHelper_Helper_' . substr($class, $strPos); - $oursFile = $this->_autoloaderClassToFile($oursClass); - $oursFile = $this->_locateClassFile($oursFile); - if (file_exists($oursFile)) { - $oursContents = file_get_contents($oursFile); - - $oursVersionId = DevHelper_Helper_ShippableHelper::getVersionId($oursClass, $oursFile, $oursContents); - if ($oursVersionId === false) { - die('DevHelper class version could not be detected: ' . $oursFile); - } - } else { - die('DevHelper file could not be found: ' . $oursFile); - } - - if ($classVersionId < $oursVersionId) { - if (!DevHelper_Helper_ShippableHelper::update($class, $classFile, $oursClass, $oursContents)) { - die('Add-on file could not be updated: ' . $classFile); - } - } - } - - return $classFile; - } - - public function getRootDir() - { - return $this->_rootDir; - } - - protected function _autoloaderClassToFile($class) - { - if (preg_match('#[^a-zA-Z0-9_\\\\]#', $class)) { - return false; - } - return $this->_rootDir . '/' . str_replace(array('_', '\\'), '/', $class) . '.php'; - } - - protected function _locateClassFile($classFile) - { - if (!empty($_SERVER['DEVHELPER_ROUTER_PHP'])) { - return DevHelper_Router::locateCached($classFile); - } - - return $classFile; - } -} diff --git a/library/DevHelper/Config/Base.php b/library/DevHelper/Config/Base.php deleted file mode 100755 index 3470ea5..0000000 --- a/library/DevHelper/Config/Base.php +++ /dev/null @@ -1,415 +0,0 @@ -_upgrade(); - - return empty($result); - } - - public function getDataClasses() - { - return $this->_dataClasses; - } - - public function getDataClass($name) - { - $name = $this->_normalizeDbName($name); - - if (!$this->checkDataClassExists($name)) { - return array(); - } - - $dataClass = $this->_dataClasses[$name]; - - foreach ($dataClass['files'] as &$file) { - if (!empty($file)) { - $path = DevHelper_Generator_File::getClassPath($file['className'], $this); - $hash = DevHelper_Generator_File::calcHash($path); - if ($hash != $file['hash']) { - $file['changed'] = true; - } - } - } - - return $dataClass; - } - - public function addDataClass( - $name, - $fields = array(), - $primaryKey = false, - $indeces = array(), - $extraData = array() - ) { - $name = $this->_normalizeDbName($name); - - $this->_dataClasses[$name] = array( - 'name' => $name, - 'camelCase' => DevHelper_Generator_File::getCamelCase($name), - 'camelCasePlural' => false, - 'camelCaseWSpace' => ucwords(str_replace('_', ' ', $name)), - 'camelCasePluralWSpace' => false, - 'fields' => array(), - 'phrases' => array(), - 'title_field' => false, - 'primaryKey' => false, - 'indeces' => array(), - - 'files' => array( - 'data_writer' => false, - 'model' => false, - 'route_prefix_admin' => false, - 'controller_admin' => false, - ), - ); - - foreach ($extraData as $key => $value) { - $this->_dataClasses[$name][$key] = $value; - } - - foreach ($fields as $fieldName => $fieldInfo) { - $fieldInfo = array_merge(array('name' => $fieldName), $fieldInfo); - $this->addDataClassField($name, $fieldInfo); - } - $this->addDataClassPrimaryKey($name, $primaryKey); - foreach ($indeces as $index) { - $this->addDataClassIndex($name, $index); - } - - return true; - } - - public function addDataClassField($name, array $field) - { - $name = $this->_normalizeDbName($name); - $field['name'] = $this->_normalizeDbName($field['name']); - $field['type'] = strtolower($field['type']); - if (!in_array($field['type'], DevHelper_Generator_Db::getDataTypes())) { - $field['type'] = XenForo_DataWriter::TYPE_SERIALIZED; - } - - if (empty($this->_dataClasses[$name]['title_field']) - && in_array( - $field['type'], - array(XenForo_DataWriter::TYPE_STRING) - ) - ) { - $this->_dataClasses[$name]['title_field'] = $field['name']; - } - - $this->_dataClasses[$name]['fields'][$field['name']] = $field; - - return true; - } - - public function addDataClassPrimaryKey($name, $fields) - { - $name = $this->_normalizeDbName($name); - - if (!is_array($fields)) { - $fields = array($fields); - } - - $primaryKey = array(); - - foreach ($fields as $field) { - $field = $this->_normalizeDbName($field); - if (!$this->checkDataClassFieldExists($name, $field)) { - return false; - } - $primaryKey[] = $field; - } - - if (!empty($primaryKey)) { - $this->_dataClasses[$name]['primaryKey'] = $primaryKey; - return true; - } - - return false; - } - - public function addDataClassIndex($name, array $index) - { - $name = $this->_normalizeDbName($name); - $fields = array(); - - if (!is_array($index['fields'])) { - $index['fields'] = array($index['fields']); - } - - foreach ($index['fields'] as $field) { - $field = $this->_normalizeDbName($field); - if ($this->checkDataClassFieldExists($name, $field)) { - $fields[] = $field; - } else { - return false; - } - } - if (empty($fields)) { - return false; - } - - if (isset($index['name'])) { - $indexName = $index['name']; - } else { - $indexName = implode('_', $fields); - } - - $type = !empty($index['type']) ? $index['type'] : 'NORMAL'; - if (!in_array(strtoupper($type), DevHelper_Generator_Db::getIndexTypes())) { - $type = 'NORMAL'; - } - - $this->_dataClasses[$name]['indeces'][$indexName] = array( - 'name' => $indexName, - 'fields' => $fields, - 'type' => strtoupper($type), - ); - - return true; - } - - public function updateDataClassFile($name, $fileType, $className, $path) - { - $name = $this->_normalizeDbName($name); - - $this->_dataClasses[$name]['files'][$fileType] = array( - 'className' => $className, - 'hash' => DevHelper_Generator_File::calcHash($path), - ); - } - - public function checkDataClassExists($name) - { - $name = $this->_normalizeDbName($name); - - return isset($this->_dataClasses[$name]); - } - - public function checkDataClassFieldExists($name, $field) - { - $name = $this->_normalizeDbName($name); - $field = $this->_normalizeDbName($field); - - return isset($this->_dataClasses[$name]['fields'][$field]); - } - - public function getDataPatches() - { - return $this->_dataPatches; - } - - public function addDataPatch($table, array $patch) - { - if (!empty($patch['index'])) { - if (!isset($patch['name'])) { - $patch['name'] = implode('_', $patch['fields']); - } - $patchKey = 'index::' . $patch['name']; - - if (isset($patch['type'])) { - $patch['type'] = strtoupper($patch['type']); - } else { - $patch['type'] = ''; - } - if (!in_array($patch['type'], DevHelper_Generator_Db::getIndexTypes())) { - $patch['type'] = 'NORMAL'; - } - - if (!isset($patch['fields'])) { - throw new XenForo_Exception('addDataPatch(index=true) requires `fields`'); - } - if (!is_array($patch['fields'])) { - $patch['fields'] = array(strval($patch['fields'])); - } - } else { - $patch['name'] = DevHelper_Generator_Db::getFieldName($this, $this->_normalizeDbName($patch['name'])); - $patchKey = $patch['name']; - - if (!isset($patch['type'])) { - throw new XenForo_Exception('addDataPatch() requires `type`'); - } - $patch['type'] = strtolower($patch['type']); - if (!in_array($patch['type'], DevHelper_Generator_Db::getDataTypes())) { - $patch['type'] = XenForo_DataWriter::TYPE_SERIALIZED; - } - } - - $this->_dataPatches[$table][$patchKey] = $patch; - - return true; - } - - public function setExportPath($path) - { - if (is_dir($path) AND is_writable($path)) { - $this->_exportPath = $path; - } else { - die('EXPORT PATH IS NOT WRITABLE'); - } - } - - public function getExportPath() - { - $path = $this->_exportPath; - - if (!is_string($path)) { - $path = ''; - } - - if (isset($_SERVER['DEVHELPER_ROUTER_PHP'])) { - $path = sprintf( - '%s/xenforo/data/exported/%s', - dirname($_SERVER['DEVHELPER_ROUTER_PHP']), - str_replace('_', DIRECTORY_SEPARATOR, $this->getClassPrefix()) - ); - XenForo_Helper_File::createDirectory($path); - } - - if ($path === '') { - // fallback - $path = DevHelper_Generator_File::getAddOnIdPath($this); - } - - if (!is_dir($path) || !is_writable($path)) { - die(sprintf('Export path (%s) is not writable', $path)); - } - - return $path; - } - - public function getExportIncludes() - { - return $this->_exportIncludes; - } - - public function getExportExcludes() - { - return $this->_exportExcludes; - } - - public function getExportAddOns() - { - return $this->_exportAddOns; - } - - public function getExportStyles() - { - return $this->_exportStyles; - } - - public function getPrefix() - { - if (!empty($this->_options['prefix'])) { - return $this->_options['prefix']; - } - - $configClassName = get_class($this); - $parts = explode('_', $configClassName); - array_pop($parts); - array_pop($parts); - $prefix = implode('_', $parts); - - return $prefix; - } - - public function getClassPrefix() - { - if (!empty($this->_options['classPrefix'])) { - return $this->_options['classPrefix']; - } - - return $this->getPrefix(); - } - - public function outputSelf() - { - $className = get_class($this); - - $dataClasses = DevHelper_Generator_File::varExport($this->_dataClasses); - $dataPatches = DevHelper_Generator_File::varExport($this->_dataPatches); - $exportPath = DevHelper_Generator_File::varExport($this->_exportPath); - $exportIncludes = DevHelper_Generator_File::varExport($this->_exportIncludes); - $exportExcludes = DevHelper_Generator_File::varExport($this->_exportExcludes); - $exportAddOns = DevHelper_Generator_File::varExport($this->_exportAddOns); - $exportStyles = DevHelper_Generator_File::varExport($this->_exportStyles); - $options = DevHelper_Generator_File::varExport($this->_options); - - $contents = <<addDataClass( - 'name_here', - array( // fields - 'field_here' => array( - 'type' => 'type_here', - // 'length' => 'length_here', - // 'required' => true, - // 'allowedValues' => array('value_1', 'value_2'), - // 'default' => 0, - // 'autoIncrement' => true, - ), - // other fields go here - ), - array('primary_key_1', 'primary_key_2'), // or 'primary_key', both are okie - array( // indeces - array( - 'fields' => array('field_1', 'field_2'), - 'type' => 'NORMAL', // UNIQUE or FULLTEXT - ), - ), - ); - */ - } -} -EOF; - - return $contents; - } - - protected function _normalizeDbName($name) - { - return $this->_normalizeName($name); - } - - protected function _normalizeName($name) - { - return preg_replace('/[^a-zA-Z_]/', '', $name); - } -} diff --git a/library/DevHelper/ControllerHelper/AddOn.php b/library/DevHelper/ControllerHelper/AddOn.php deleted file mode 100644 index 894ff69..0000000 --- a/library/DevHelper/ControllerHelper/AddOn.php +++ /dev/null @@ -1,65 +0,0 @@ -Sync Now.', - XenForo_Link::buildAdminLink('tools/dev/helper/sync') - )); - } - } - - public function filterKeepActiveAddOns(array &$dataGrouped, array $addOns = null) - { - $removedCount = 0; - - if ($addOns === null) { - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = $this->_controller->getModelFromCache('XenForo_Model_AddOn'); - $addOns = $addOnModel->getAllAddOns(); - } - - foreach ($addOns as $addOn) { - if (empty($addOn['active'])) { - // remove template modifications from inactive add-ons - if (!empty($dataGrouped[$addOn['addon_id']])) { - $removedCount += count($dataGrouped[$addOn['addon_id']]); - unset($dataGrouped[$addOn['addon_id']]); - } - } - } - - return $removedCount; - } - - public function filterKeepActiveAddOnsDirect(array &$data, array $addOns = null) - { - $removedCount = 0; - - if ($addOns === null) { - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = $this->_controller->getModelFromCache('XenForo_Model_AddOn'); - $addOns = $addOnModel->getAllAddOns(); - } - - foreach (array_keys($data) as $dataId) { - $singleRef = &$data[$dataId]; - - if (empty($addOns[$singleRef['addon_id']])) { - continue; - } - $addOnRef = &$addOns[$singleRef['addon_id']]; - - if (empty($addOnRef['active'])) { - $removedCount++; - unset($data[$dataId]); - } - } - - return $removedCount; - } -} diff --git a/library/DevHelper/Generator/Code/Common.php b/library/DevHelper/Generator/Code/Common.php deleted file mode 100755 index b4d5db9..0000000 --- a/library/DevHelper/Generator/Code/Common.php +++ /dev/null @@ -1,233 +0,0 @@ -_className === false) { - throw new Exception('_setClassName() must be called before calling _generate()'); - } - - $output = ''; - - $output .= "_className}"; - if ($this->_baseClass !== false) { - $output .= " extends {$this->_baseClass}"; - } - if (!empty($this->_interfaces)) { - $isFirstInterface = true; - $output .= " implements"; - foreach ($this->_interfaces as $interface) { - if ($isFirstInterface) { - $isFirstInterface = false; - } else { - $output .= ","; - } - $output .= " {$interface}"; - } - } - $output .= "\n{\n"; - - $output .= "\n " . DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START . "\n"; - - if (!empty($this->_constants)) { - $output .= "\n"; - foreach ($this->_constants as $constantName => $constantValue) { - $output .= " const {$constantName} = {$constantValue};\n"; - } - } - - if (!empty($this->_properties)) { - $output .= "\n"; - foreach ($this->_properties as $propertyName => $propertyDeclare) { - if ($propertyDeclare != null) { - $output .= " {$propertyDeclare};\n"; - } else { - $output .= " protected {$propertyName};\n"; - } - } - } - - if (!empty($this->_methods)) { - foreach ($this->_methods as $method) { - $output .= "\n"; - $output .= $this->_generateMethod($method); - } - } - - $output .= "\n " . DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END . "\n"; - - if (!empty($this->_customizableMethods)) { - foreach ($this->_customizableMethods as $method) { - $output .= "\n"; - $output .= $this->_generateMethod($method); - } - } - - $output .= "\n"; - - // class ClassName { - $output .= "}\n"; - - return $output; - } - - protected function _generateMethod($method, $level = 1) - { - $output = ""; - $indentation = str_repeat(" ", $level); - - $output .= $indentation; - if ($method['visibility'] != '') { - $output .= "{$method['visibility']} "; - } - $output .= "function {$method['name']}("; - - $isFirstParam = true; - foreach ($method['params'] as $paramName => $paramDeclare) { - if ($isFirstParam) { - $isFirstParam = false; - } else { - $output .= ", "; - } - - if ($paramDeclare != null) { - $output .= "{$paramDeclare}"; - } else { - $output .= "{$paramName}"; - } - } - - $output .= ")\n {\n"; - - $codeBlocks = $method['code']; - ksort($codeBlocks); - $isFirstCodeBlock = true; - foreach ($codeBlocks as $codeBlock) { - $lines = explode("\n", $codeBlock); - $codeBlockOutput = ''; - $foundNonEmptyLine = false; - - foreach ($lines as $line) { - $trimmed = trim($line); - - if (strlen($trimmed) == 0) { - // this is an empty line, only output if we have found some non-empty line before - if ($foundNonEmptyLine) { - $codeBlockOutput .= "\n"; - } - } else { - $foundNonEmptyLine = true; - $codeBlockOutput .= "{$indentation} {$line}\n"; - } - } - - // remove the last empty lines - $codeBlockOutput = rtrim($codeBlockOutput); - - if ($isFirstCodeBlock) { - $isFirstCodeBlock = false; - } else { - $output .= "\n"; - } - $output .= $codeBlockOutput . "\n"; - } - - $output .= "{$indentation}}\n"; - - return $output; - } - - protected function _setClassName($className) - { - $this->_className = $className; - } - - protected function _setBaseClass($className) - { - $this->_baseClass = $className; - } - - protected function _addInterface($interface) - { - $this->_interfaces[] = $interface; - } - - protected function _addConstant($name, $value) - { - $this->_constants[$name] = $value; - } - - protected function _addProperty($name, $declare = null) - { - $this->_properties[$name] = $declare; - } - - protected function _addMethod($name, $visibility, array $params, $code, $codeId = null) - { - $this->_addMethodCommon($this->_methods, $name, $visibility, $params); - - // switch code with existing code (detected by codeId) if needed - if (!empty($code)) { - if ($codeId !== null) { - $this->_methods[$name]['code'][$codeId] = $code; - } else { - $this->_methods[$name]['code'][] = $code; - } - } - } - - protected function _addCustomizableMethod($name, $visibility, array $params) - { - $this->_addMethodCommon($this->_customizableMethods, $name, $visibility, $params); - - $this->_customizableMethods[$name]['code'] = array('// customized code goes here'); - } - - protected function _addMethodCommon(array &$methods, $name, $visibility, $params) - { - if (!isset($methods[$name])) { - $methods[$name] = array( - 'name' => $name, - 'visibility' => '', - 'params' => array(), - 'code' => array(), - ); - } - - // we have to use the broader visibility between - static $visibilities = array( - '', - 'private', - 'protected', - 'public', - 'protected static', - 'public static' - ); - $oldVisibilityLevel = array_search($methods[$name]['visibility'], $visibilities); - $newVisibilityLevel = array_search($visibility, $visibilities); - $max = max(array( - $oldVisibilityLevel, - $newVisibilityLevel - )); - $methods[$name]['visibility'] = $visibilities[$max]; - - foreach ($params as $paramName => $paramDeclare) { - if (is_numeric($paramName)) { - $paramName = $paramDeclare; - $paramDeclare = null; - } - $methods[$name]['params'][$paramName] = $paramDeclare; - } - } -} diff --git a/library/DevHelper/Generator/Code/ControllerAdmin.php b/library/DevHelper/Generator/Code/ControllerAdmin.php deleted file mode 100755 index 9d13a9d..0000000 --- a/library/DevHelper/Generator/Code/ControllerAdmin.php +++ /dev/null @@ -1,724 +0,0 @@ -_addOn = $addOn; - $this->_config = $config; - $this->_dataClass = $dataClass; - $this->_info = $info; - } - - protected function _generate() - { - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate %s: too many fields in primary key', - $this->_info['controller'] - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - $variableName = DevHelper_Generator_Code_Model::getVariableName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $variableNamePlural = DevHelper_Generator_Code_Model::getVariableNamePlural( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $modelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $modelGetFunctionName = DevHelper_Generator_Code_Model::generateGetDataFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $dataWriterClassName = DevHelper_Generator_Code_DataWriter::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $viewListClassName = $this->_getViewClassName('list'); - $viewEditClassName = $this->_getViewClassName('edit'); - $viewDeleteClassName = $this->_getViewClassName('delete'); - - $imageField = DevHelper_Generator_Db::getImageField($this->_dataClass['fields']); - list($templateList, $templateEdit, $templateDelete) = $this->_generateTemplates( - $variableName, - $variableNamePlural, - $imageField - ); - - $this->_setClassName($this->_info['controller']); - $this->_setBaseClass('XenForo_ControllerAdmin_Abstract'); - - $actionIndexConditions = array(); - $actionIndexFetchOptions = array(); - - if (isset($this->_dataClass['fields']['display_order'])) { - $actionIndexFetchOptions['order'] = 'display_order'; - } - - $actionIndexConditions = DevHelper_Generator_File::varExport($actionIndexConditions); - $actionIndexFetchOptions = DevHelper_Generator_File::varExport($actionIndexFetchOptions); - - $this->_addMethod('actionIndex', 'public', array(), " - -\$conditions = {$actionIndexConditions}; -\$fetchOptions = {$actionIndexFetchOptions}; - -\${$variableName}Model = \$this->_get{$this->_dataClass['camelCase']}Model(); -\${$variableNamePlural} = \${$variableName}Model->{$modelGetFunctionName}(\$conditions, \$fetchOptions); - -\$viewParams = array( - '{$variableNamePlural}' => \${$variableNamePlural}, -); - -return \$this->responseView('$viewListClassName', '$templateList', \$viewParams); - "); - - $this->_addMethod('actionAdd', 'public', array(), " - -\$viewParams = array( - '$variableName' => array(), -); - - ", '000'); - - $this->_addMethod('actionAdd', 'public', array(), " - -return \$this->responseView('$viewEditClassName', '$templateEdit', \$viewParams); - - ", '999'); - - $this->_addMethod('actionEdit', 'public', array(), " - -\$id = \$this->_input->filterSingle('{$idField}', XenForo_Input::UINT); -\${$variableName} = \$this->_get{$this->_dataClass['camelCase']}OrError(\$id); - -\$viewParams = array( - '$variableName' => \${$variableName}, -); - - ", '000'); - - $this->_addMethod('actionEdit', 'public', array(), " - -return \$this->responseView('$viewEditClassName', '$templateEdit', \$viewParams); - - ", '999'); - - $this->_addMethod('actionSave', 'public', array(), " - -\$this->_assertPostOnly(); - -\$id = \$this->_input->filterSingle('{$idField}', XenForo_Input::UINT); -\$dw = \$this->_get{$this->_dataClass['camelCase']}DataWriter(); -if (\$id) { - \$dw->setExistingData(\$id); -} - - ", '000'); - - $this->_addMethod('actionSave', 'public', array(), " - -\$this->_prepareDwBeforeSaving(\$dw); - -\$dw->save(); - -return \$this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('{$this->_info['routePrefix']}') -); - - ", '999'); - - $this->_addMethod('actionDelete', 'public', array(), " - -\$id = \$this->_input->filterSingle('{$idField}', XenForo_Input::UINT); -\${$variableName} = \$this->_get{$this->_dataClass['camelCase']}OrError(\$id); - -if (\$this->isConfirmedPost()) { - \$dw = \$this->_get{$this->_dataClass['camelCase']}DataWriter(); - \$dw->setExistingData(\$id); - \$dw->delete(); - - return \$this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('{$this->_info['routePrefix']}') - ); -} else { - \$viewParams = array( - '$variableName' => \${$variableName}, - ); - - return \$this->responseView('$viewDeleteClassName', '$templateDelete', \$viewParams); -} - - "); - - $phraseNotFound = $this->_getPhraseName('_not_found'); - $this->_addMethod("_get{$this->_dataClass['camelCase']}OrError", 'protected', array( - '$id', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\${$variableName} = \$this->_get{$this->_dataClass['camelCase']}Model()->get{$this->_dataClass['camelCase']}ById(\$id, \$fetchOptions); - -if (empty(\${$variableName})) { - throw \$this->responseException(\$this->responseError(new XenForo_Phrase('$phraseNotFound'), 404)); -} - -return \${$variableName}; - - "); - - $this->_addMethod("_get{$this->_dataClass['camelCase']}Model", 'protected', array(), " - -return \$this->getModelFromCache('$modelClassName'); - - "); - - $this->_addMethod(" _get{$this->_dataClass['camelCase']}DataWriter", 'protected', array(), " - -return XenForo_DataWriter::create('$dataWriterClassName'); - - "); - - $this->_addCustomizableMethod( - '_prepareDwBeforeSaving', - 'protected', - array('$dw' => "$dataWriterClassName \$dw") - ); - - return parent::_generate(); - } - - protected function _generateTemplates($variableName, $variableNamePlural, $imageField) - { - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate %s: too many fields in primary key', - $this->_info['controller'] - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - $dataTitle = "\${$variableName}" - . ( - empty($this->_dataClass['title_field']) - ? (".{$idField}") - : ( - is_array($this->_dataClass['title_field']) - ? (".{$this->_dataClass['title_field'][0]}.{$this->_dataClass['title_field'][1]}") - : (".{$this->_dataClass['title_field']}") - )); - - // create the phrases - $phraseClassName = $this->_getPhraseName(''); - $phrasePlural = $this->_getPhrasePluralName(); - $phraseAdd = $this->_getPhraseName('_add'); - $phraseEdit = $this->_getPhraseName('_edit'); - $phraseDelete = $this->_getPhraseName('_delete'); - $phraseSave = $this->_getPhraseName('_save'); - $phraseConfirmDeletion = $this->_getPhraseName('_confirm_deletion'); - $phrasePleaseConfirm = $this->_getPhraseName('_please_confirm'); - $phraseNotFound = $this->_getPhraseName('_not_found'); - $phraseNoResults = $this->_getPhraseName('_no_results'); - - $this->_generatePhrase($phraseClassName, $this->_dataClass['camelCaseWSpace']); - if (!empty($this->_dataClass['camelCasePluralWSpace'])) { - $this->_generatePhrase($phrasePlural, $this->_dataClass['camelCasePluralWSpace']); - } else { - $this->_generatePhrase($phrasePlural, $this->_dataClass['camelCaseWSpace'] . ' (Plural)'); - } - $this->_generatePhrase($phraseAdd, 'Add New ' . $this->_dataClass['camelCaseWSpace']); - $this->_generatePhrase($phraseEdit, 'Edit ' . $this->_dataClass['camelCaseWSpace']); - $this->_generatePhrase($phraseDelete, 'Delete ' . $this->_dataClass['camelCaseWSpace']); - $this->_generatePhrase($phraseSave, 'Save ' . $this->_dataClass['camelCaseWSpace']); - $this->_generatePhrase($phraseConfirmDeletion, 'Confirm Deletion of ' . $this->_dataClass['camelCaseWSpace']); - $this->_generatePhrase( - $phrasePleaseConfirm, - 'Please confirm that you want to delete the following ' . strtolower($this->_dataClass['camelCaseWSpace']) - ); - $this->_generatePhrase( - $phraseNotFound, - 'The requested ' . strtolower($this->_dataClass['camelCaseWSpace']) . ' could not be found' - ); - $this->_generatePhrase( - $phraseNoResults, - 'No ' . strtolower($this->_dataClass['camelCaseWSpace']) . ' could be found...' - ); - // finished creating pharses - - $templateList = $this->_getTemplateTitle('_list'); - $templateListItems = $this->_getTemplateTitle('_list_items'); - $templateEdit = $this->_getTemplateTitle('_edit'); - $templateDelete = $this->_getTemplateTitle('_delete'); - - // create the templates - $listItemExtras = ''; - if ($imageField !== false) { - $listItemExtras .= << - {xen:if '{\${$variableName}.images.s}', ''} - -EOF; - } - - $templateListItemsTemplate = << - - {{$dataTitle}}{$listItemExtras} - - -EOF; - $this->_generateAdminTemplate($templateListItems, $templateListItemsTemplate); - // finished template_list_items - - $templateListTemplate = <<{xen:phrase $phrasePlural} - - - + {xen:phrase $phraseAdd} - - - - - - - -

- - {xen:phrase $phrasePlural} -

- -
    - -
- - - -
{xen:phrase $phraseNoResults}
-
-
-EOF; - $this->_generateAdminTemplate($templateList, $templateListTemplate); - // finished template_list - - $templateEditFormExtra = 'class="AutoValidator" data-redirect="yes"'; - $templateEditFields = ''; - $extraViewParamsForTemplateEdit = array(); - $filterParams = array(); - - if (!empty($this->_dataClass['phrases'])) { - foreach ($this->_dataClass['phrases'] as $phraseType) { - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $this->_dataClass['name'] . '_' . $phraseType - ); - - $templateEditFields .= << -EOF; - } - } - - foreach ($this->_dataClass['fields'] as $field) { - if ($field['name'] == $idField) { - continue; - } - if (empty($field['required'])) { - // ignore non-required fields - continue; - } - if ($field['name'] == $imageField) { - // ignore image field - continue; - } - - // queue this field for validation - $filterParams[$field['name']] = $field['type']; - - if ($field['name'] == $this->_dataClass['title_field']) { - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $field['name'] - ); - $templateEditFields .= << -EOF; - continue; - } - - if (substr($field['name'], -3) == '_id') { - // link to another dataClass? - $other = substr($field['name'], 0, -3); - if ($this->_config->checkDataClassExists($other)) { - // yeah! - $otherDataClass = $this->_config->getDataClass($other); - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $otherDataClass, - $otherDataClass['name'] - ); - $templateEditFields .= << -   - - -EOF; - $otherDataClassModelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $otherDataClass - ); - $extraViewParamsForTemplateEdit["list{$otherDataClass['camelCase']}"] = - "\$viewParams['list{$otherDataClass['camelCase']}'] = " . - "\$this->getModelFromCache('{$otherDataClassModelClassName}')->getList();"; - continue; - } elseif ($other === $this->_dataClass['name'] . '_parent') { - // just a parent of this same class - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $other - ); - $templateEditFields .= << -   - - -EOF; - $thisDataClassModelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $extraViewParamsForTemplateEdit["list{$this->_dataClass['camelCase']}"] = - "\$viewParams['list{$this->_dataClass['camelCase']}'] = " . - "\$this->getModelFromCache('{$thisDataClassModelClassName}')->getList();"; - continue; - } - } - - if ($field['name'] == 'display_order') { - // special case with display_order - $templateEditFields .= << -EOF; - continue; - } - - if ($field['type'] == 'string' && !empty($field['allowedValues'])) { - // render field with enum type as a list of selections - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $field['name'] - ); - - $templateEditFields .= << -   -EOF; - - foreach ($field['allowedValues'] as $allowedValue) { - $allowedValuePhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $field['name'] . '_' . $allowedValue - ); - - $templateEditFields .= <<{xen:phrase $allowedValuePhraseName} -EOF; - } - - $templateEditFields .= << -EOF; - - continue; - } - - if ($field['type'] == 'uint' AND substr($field['name'], 0, 3) === 'is_') { - // special case with boolean fields - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $field['name'] - ); - - $templateEditFields .= << - - -EOF; - - continue; - } - - $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $field['name'] - ); - $extra = ''; - if ($field['type'] == XenForo_DataWriter::TYPE_STRING AND (empty($field['length']) OR $field['length'] > 255)) { - $extra .= ' rows="5"'; - } - $templateEditFields .= << -EOF; - } - - if ($imageField !== false) { - $fieldPhraseImage = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle( - $this->_addOn, - $this->_config, - $this->_dataClass, - 'image' - ); - $templateEditFormExtra = 'enctype="multipart/form-data"'; - - $templateEditFields .= << -
- - - {\$imageSizeCode} - - -
- -EOF; - } - - $templateEditTemplate = <<{xen:if '{\${$variableName}.{$idField}}', '{xen:phrase $phraseEdit}', '{xen:phrase $phraseAdd}'} - - - - $templateEditFields - - - - - - - -EOF; - - $this->_generateAdminTemplate($templateEdit, $templateEditTemplate); - - // add extra code for add, edit actions - if (!empty($extraViewParamsForTemplateEdit)) { - $this->_addMethod('actionAdd', 'public', array(), implode("\n", $extraViewParamsForTemplateEdit), '100'); - $this->_addMethod('actionEdit', 'public', array(), implode("\n", $extraViewParamsForTemplateEdit), '100'); - } - - // add input fields to action save - if (!empty($this->_dataClass['phrases'])) { - $phraseCode = "\$phrases = \$this->_input->filterSingle('_phrases', XenForo_Input::ARRAY_SIMPLE);\n"; - foreach ($this->_dataClass['phrases'] as $phraseType) { - $dataWriterClassName = DevHelper_Generator_Code_DataWriter::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $dataPhraseConstantName = DevHelper_Generator_Code_DataWriter::generateDataPhraseConstant( - $this->_addOn, - $this->_config, - $this->_dataClass, - $phraseType - ); - - $phraseCode .= "if (isset(\$phrases['{$phraseType}']))\n{\n"; - $phraseCode .= " \$dw->setExtraData({$dataWriterClassName}::{$dataPhraseConstantName}, \$phrases['{$phraseType}']);\n"; - $phraseCode .= "}\n"; - } - - $this->_addMethod('actionSave', 'public', array(), " - -// get phrases from input data -{$phraseCode} - - ", '100'); - } - - if (!empty($filterParams)) { - $filterParamsExported = DevHelper_Generator_File::varExport($filterParams, 1); - $this->_addMethod('actionSave', 'public', array(), " - -// get regular fields from input data -\$dwInput = \$this->_input->filter($filterParamsExported); -\$dw->bulkSet(\$dwInput); - - ", '200'); - } - - if ($imageField !== false) { - // add image to action save - $this->_addMethod('actionSave', 'public', array(), " - -// try to save the uploaded image if any -\$image = XenForo_Upload::getUploadedFile('image'); -if (!empty(\$image)) { - \$dw->setImage(\$image); -} - - ", '300'); - } - // finished template_edit - - $templateDeleteTemplate = <<{xen:phrase $phraseConfirmDeletion}: {{$dataTitle}} -{xen:phrase $phraseConfirmDeletion} - - - {{$dataTitle}} - - - - - - -

{xen:phrase $phrasePleaseConfirm}:

- {{$dataTitle}} - - - - -
-EOF; - $this->_generateAdminTemplate($templateDelete, $templateDeleteTemplate); - - // finished creating our templates - - return array( - $templateList, - $templateEdit, - $templateDelete, - ); - } - - protected function _getPhraseName($suffix) - { - return DevHelper_Generator_Phrase::getPhraseName( - $this->_addOn, - $this->_config, - $this->_dataClass, - $this->_dataClass['name'] . $suffix - ); - } - - protected function _getPhrasePluralName() - { - if (!empty($this->_dataClass['camelCasePluralWSpace'])) { - $phrase = strtolower(str_replace(' ', '_', $this->_dataClass['camelCasePluralWSpace'])); - } else { - $phrase = $this->_dataClass['name'] . '_plural'; - } - - return DevHelper_Generator_Phrase::getPhraseName($this->_addOn, $this->_config, $this->_dataClass, $phrase); - } - - protected function _generatePhrase($phraseName, $phraseText) - { - DevHelper_Generator_Phrase::generatePhrase($this->_addOn, $phraseName, $phraseText); - } - - protected function _getTemplateTitle($suffix) - { - return DevHelper_Generator_Template::getTemplateTitle( - $this->_addOn, - $this->_config, - $this->_dataClass, - $this->_dataClass['name'] . $suffix - ); - } - - protected function _generateAdminTemplate($templateTitle, $templateHtml) - { - DevHelper_Generator_Template::generateAdminTemplate($this->_addOn, $templateTitle, $templateHtml); - } - - protected function _getClassName() - { - return self::getClassName($this->_addOn, $this->_config, $this->_dataClass); - } - - protected function _getViewClassName($view) - { - $subClassName = 'ViewAdmin_' . $this->_dataClass['camelCase'] . '_' . ucwords($view); - - return DevHelper_Generator_File::getClassName($this->_addOn['addon_id'], $subClassName, $this->_config); - } - - public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass, array $info) - { - $g = new self($addOn, $config, $dataClass, $info); - - return array( - $g->_getClassName(), - $g->_generate() - ); - } - - public static function getClassName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return DevHelper_Generator_File::getClassName( - $addOn['addon_id'], - 'ControllerAdmin_' . $dataClass['camelCase'], - $config - ); - } -} diff --git a/library/DevHelper/Generator/Code/DataWriter.php b/library/DevHelper/Generator/Code/DataWriter.php deleted file mode 100755 index 40ea5fc..0000000 --- a/library/DevHelper/Generator/Code/DataWriter.php +++ /dev/null @@ -1,395 +0,0 @@ -_addOn = $addOn; - $this->_config = $config; - $this->_dataClass = $dataClass; - } - - protected function _generate() - { - $className = $this->_getClassName(); - $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); - $tableFields = $this->_dataClass['fields']; - foreach ($tableFields as &$field) { - unset($field['name']); - if (!empty($field['length'])) { - $field['maxLength'] = $field['length']; - unset($field['length']); - } - - $field['type'] = DevHelper_Generator_File::varExportConstantFromArray($field['type'], array( - 'XenForo_DataWriter::TYPE_BOOLEAN', - 'XenForo_DataWriter::TYPE_STRING', - 'XenForo_DataWriter::TYPE_BINARY', - 'XenForo_DataWriter::TYPE_INT', - 'XenForo_DataWriter::TYPE_UINT', - 'XenForo_DataWriter::TYPE_UINT_FORCED', - 'XenForo_DataWriter::TYPE_FLOAT', - 'XenForo_DataWriter::TYPE_SERIALIZED', - 'XenForo_DataWriter::TYPE_JSON', - 'XenForo_DataWriter::TYPE_UNKNOWN', - )); - } - $tableFields = DevHelper_Generator_File::varExport($tableFields, 1); - $primaryKey = DevHelper_Generator_File::varExport($this->_dataClass['primaryKey']); - $modelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $this->_setClassName($className); - $this->_setBaseClass('XenForo_DataWriter'); - - $this->_addMethod('_getFields', 'protected', array(), " - -return array( - '{$tableName}' => {$tableFields} -); - - "); - - if (count($this->_dataClass['primaryKey']) == 1) { - $idField = reset($this->_dataClass['primaryKey']); - $this->_addMethod('_getExistingData', 'protected', array('$data'), " - -if (!\$id = \$this->_getExistingPrimaryKey(\$data, '{$idField}')) { - return false; -} - -return array('$tableName' => \$this->_get{$this->_dataClass['camelCase']}Model()->get{$this->_dataClass['camelCase']}ById(\$id)); - - "); - } else { - $this->_addMethod('_getExistingData', 'protected', array('$data'), " - -throw new XenForo_Exception('{$className} does not support _getExistingData()'); - - "); - } - - $this->_addMethod('_getUpdateCondition', 'protected', array('$tableName'), " - -\$conditions = array(); - -foreach ($primaryKey as \$field) { - \$conditions[] = \$field . ' = ' . \$this->_db->quote(\$this->getExisting(\$field)); -} - -return implode(' AND ', \$conditions); - - "); - - $this->_addMethod("_get{$this->_dataClass['camelCase']}Model", 'protected', array(), " - -return \$this->getModelFromCache('$modelClassName'); - - "); - - $this->_generateImageCode(); - $this->_generatePhrasesCode(); - $this->_generateParentCode(); - - return parent::_generate(); - } - - protected function _generateImageCode() - { - $imageField = DevHelper_Generator_Db::getImageField($this->_dataClass['fields']); - if ($imageField === false) { - // no image field... - return false; - } - - $modelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $this->_addConstant('DATA_IMAGE_PREPARED', '\'imagePrepared\''); - $this->_addConstant('IMAGE_SIZE_ORIGINAL', '-1'); - $this->_addProperty('$imageQuality', 'public static $imageQuality = 85'); - - $this->_addMethod('setImage', 'public', array('$upload' => 'XenForo_Upload $upload'), " - -if (!\$upload->isValid()) { - throw new XenForo_Exception(\$upload->getErrors(), true); -} - -if (!\$upload->isImage()) { - throw new XenForo_Exception(new XenForo_Phrase('uploaded_file_is_not_valid_image'), true); -}; - -\$imageType = \$upload->getImageInfoField('type'); -if (!in_array(\$imageType, array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { - throw new XenForo_Exception(new XenForo_Phrase('uploaded_file_is_not_valid_image'), true); -} - -\$this->setExtraData(self::DATA_IMAGE_PREPARED, \$this->_prepareImage(\$upload)); -\$this->set('{$imageField}', XenForo_Application::\$time); - - "); - - $this->_addMethod('_prepareImage', 'protected', array('$upload' => 'XenForo_Upload $upload'), " - -\$outputFiles = array(); -\$fileName = \$upload->getTempFile(); -\$imageType = \$upload->getImageInfoField('type'); -\$outputType = \$imageType; -\$width = \$upload->getImageInfoField('width'); -\$height = \$upload->getImageInfoField('height'); - -\$imageSizes = \$this->getImageSizes(); -reset(\$imageSizes); - -while (list(\$sizeCode, \$maxDimensions) = each(\$imageSizes)) { - \$newTempFile = tempnam(XenForo_Helper_File::getTempDir(), 'xfa'); - - if (\$maxDimensions == self::IMAGE_SIZE_ORIGINAL) { - copy(\$fileName, \$newTempFile); - } else { - \$image = XenForo_Image_Abstract::createFromFile(\$fileName, \$imageType); - if (!\$image) { - continue; - } - - \$image->thumbnailFixedShorterSide(\$maxDimensions); - if (\$image->getWidth() > \$maxDimensions OR \$image->getHeight() > \$maxDimensions) { - \$image->crop(0, 0, \$maxDimensions, \$maxDimensions); - } - - \$image->output(\$outputType, \$newTempFile, self::\$imageQuality); - unset(\$image); - } - - \$outputFiles[\$sizeCode] = \$newTempFile; -} - -if (count(\$outputFiles) != count(\$imageSizes)) { - foreach (\$outputFiles AS \$tempFile) { - if (\$tempFile != \$fileName) { - @unlink(\$tempFile); - } - } - - throw new XenForo_Exception('Non-image passed in to _prepareImage'); -} - -return \$outputFiles; - - "); - - $this->_addMethod('_moveImages', 'protected', array('$uploaded'), " - -if (is_array(\$uploaded)) { - \$data = \$this->getMergedData(); - foreach (\$uploaded as \$sizeCode => \$tempFile) { - \$filePath = {$modelClassName}::getImageFilePath(\$data, \$sizeCode); - \$directory = dirname(\$filePath); - - if (XenForo_Helper_File::createDirectory(\$directory, true)) { - XenForo_Helper_File::safeRename(\$tempFile, \$filePath); - } - } -} - - "); - - $this->_addMethod('_postSave', 'protected', array(), " - -\$uploaded = \$this->getExtraData(self::DATA_IMAGE_PREPARED); -if (\$uploaded) { - \$this->_moveImages(\$uploaded); - - if (\$this->isUpdate()) { - // removes old image - \$existingData = \$this->getMergedExistingData(); - foreach (array_keys(\$this->getImageSizes()) as \$sizeCode) { - \$filePath = {$modelClassName}::getImageFilePath(\$existingData, \$sizeCode); - @unlink(\$filePath); - } - } -} - - "); - - $this->_addMethod('_postDelete', 'protected', array(), " - -\$existingData = \$this->getMergedExistingData(); -foreach (array_keys(\$this->getImageSizes()) as \$sizeCode) { - \$filePath = {$modelClassName}::getImageFilePath(\$existingData, \$sizeCode); - @unlink(\$filePath); -} - - "); - - $this->_addMethod('getImageSizes', 'public', array(), " - -return array( - 'x' => self::IMAGE_SIZE_ORIGINAL, - 'l' => 96, - 'm' => 48, - 's' => 24 -); - - "); - - return true; - } - - protected function _generatePhrasesCode() - { - if (!empty($this->_dataClass['phrases'])) { - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate phrases code for %s: too many fields in primary key', - $this->_getClassName() - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - foreach ($this->_dataClass['phrases'] as $phraseType) { - $camelCase = ucwords(str_replace('_', ' ', $phraseType)); - $constantName = self::generateDataPhraseConstant( - $this->_addOn, - $this->_config, - $this->_dataClass, - $phraseType - ); - $modelClassName = DevHelper_Generator_Code_Model::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $getPhraseTitleFunction = DevHelper_Generator_Code_Model::generateGetPhraseTitleFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass, - $phraseType - ); - - $this->_addConstant($constantName, "'phrase{$camelCase}'"); - - $this->_addMethod('_postSave', 'protected', array(), " - -\$phrase{$camelCase} = \$this->getExtraData(self::{$constantName}); -if (\$phrase{$camelCase} !== null) { - \$this->_insertOrUpdateMasterPhrase({$modelClassName}::{$getPhraseTitleFunction}(\$this->get('{$idField}')), \$phrase{$camelCase}); -} - - "); - - $this->_addMethod('_postDelete', 'protected', array(), " - -\$this->_deleteMasterPhrase({$modelClassName}::{$getPhraseTitleFunction}(\$this->get('{$idField}'))); - - "); - } - } - } - - protected function _generateParentCode() - { - $parentField = DevHelper_Generator_Db::getParentField($this->_dataClass['name'], $this->_dataClass['fields']); - if ($parentField === false) { - // no parent field... - return; - } - - $displayOrderField = false; - $depthField = false; - $lftField = false; - $rgtField = false; - foreach ($this->_dataClass['fields'] as $field) { - if ($field['name'] == 'display_order') { - $displayOrderField = $field['name']; - } elseif ($field['name'] == 'depth') { - $depthField = $field['name']; - } elseif ($field['name'] == 'lft') { - $lftField = $field['name']; - } elseif ($field['name'] == 'rgt') { - $rgtField = $field['name']; - } - } - if (empty($displayOrderField) OR empty($depthField) OR empty($lftField) OR empty($rgtField)) { - // no hierarchy fields - return; - } - - $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); - $rebuildStructureFunctionName = DevHelper_Generator_Code_Model::generateRebuildStructureFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $titleFieldPostSaveConditions = ''; - if (!empty($this->_dataClass['title_field']) AND !is_array($this->_dataClass['title_field'])) { - $titleFieldPostSaveConditions = "\n OR \$this->isChanged('{$this->_dataClass['title_field']}')"; - } - - $this->_addMethod('_postSave', 'protected', array(), " - -if (\$this->isInsert() - OR \$this->isChanged('{$displayOrderField}') - OR \$this->isChanged('{$parentField}'){$titleFieldPostSaveConditions} -) { - \$this->_get{$this->_dataClass['camelCase']}Model()->{$rebuildStructureFunctionName}(); -} - - "); - - $this->_addMethod('_postDelete', 'protected', array(), " - -\$this->_db->update('{$tableName}', - array('{$parentField}' => \$this->get('{$parentField}')), - '{$parentField} = ' . \$this->_db->quote(\$this->get('{$parentField}')) -); - -\$this->_get{$this->_dataClass['camelCase']}Model()->{$rebuildStructureFunctionName}(); - - "); - } - - protected function _getClassName() - { - return self::getClassName($this->_addOn, $this->_config, $this->_dataClass); - } - - public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $g = new self($addOn, $config, $dataClass); - - return array( - $g->_getClassName(), - $g->_generate() - ); - } - - public static function getClassName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return DevHelper_Generator_File::getClassName( - $addOn['addon_id'], - 'DataWriter_' . $dataClass['camelCase'], - $config - ); - } - - public static function generateDataPhraseConstant( - array $addOn, - DevHelper_Config_Base $config, - array $dataClass, - $phraseType - ) { - return 'DATA_PHRASE_' . strtoupper($phraseType); - } -} diff --git a/library/DevHelper/Generator/Code/Installer.php b/library/DevHelper/Generator/Code/Installer.php deleted file mode 100755 index 69e8818..0000000 --- a/library/DevHelper/Generator/Code/Installer.php +++ /dev/null @@ -1,133 +0,0 @@ -getDataClasses(); - foreach ($dataClasses as $dataClass) { - $table = array(); - $table['createQuery'] = DevHelper_Generator_Db::createTable($config, $dataClass); - $table['dropQuery'] = DevHelper_Generator_Db::dropTable($config, $dataClass); - - $tables[$dataClass['name']] = $table; - } - $tables = DevHelper_Generator_File::varExport($tables); - - $patches = array(); - $dataPatches = $config->getDataPatches(); - foreach ($dataPatches as $table => $tablePatches) { - foreach ($tablePatches as $dataPatch) { - $patch = array(); - $patch['table'] = $table; - $patch['tableCheckQuery'] = DevHelper_Generator_Db::showTables($config, $table); - - if (!empty($dataPatch['index'])) { - $patch['index'] = $dataPatch['name']; - $patch['checkQuery'] = DevHelper_Generator_Db::showIndexes($config, $table, $dataPatch); - $patch['addQuery'] = DevHelper_Generator_Db::alterTableAddIndex($config, $table, $dataPatch); - $patch['dropQuery'] = DevHelper_Generator_Db::alterTableDropIndex($config, $table, $dataPatch); - } else { - $patch['field'] = $dataPatch['name']; - $patch['checkQuery'] = DevHelper_Generator_Db::showColumns($config, $table, $dataPatch); - $patch['addQuery'] = DevHelper_Generator_Db::alterTableAddColumn($config, $table, $dataPatch); - $patch['modifyQuery'] = DevHelper_Generator_Db::alterTableModifyColumn($config, $table, $dataPatch); - $patch['dropQuery'] = DevHelper_Generator_Db::alterTableDropColumn($config, $table, $dataPatch); - } - - $patches[] = $patch; - } - } - $patches = DevHelper_Generator_File::varExport($patches); - - $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; - $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; - - $contents = <<query(\$table['createQuery']); - } - - foreach (self::\$_patches as \$patch) { - \$tableExisted = \$db->fetchOne(\$patch['tableCheckQuery']); - if (empty(\$tableExisted)) { - continue; - } - - \$existed = \$db->fetchOne(\$patch['checkQuery']); - if (empty(\$existed)) { - \$db->query(\$patch['addQuery']); - } elseif (!empty(\$patch['modifyQuery'])) { - \$db->query(\$patch['modifyQuery']); - } - } - - self::installCustomized(\$existingAddOn, \$addOnData); - } - - public static function uninstall() - { - \$db = XenForo_Application::get('db'); - - foreach (self::\$_patches as \$patch) { - \$tableExisted = \$db->fetchOne(\$patch['tableCheckQuery']); - if (empty(\$tableExisted)) { - continue; - } - - \$existed = \$db->fetchOne(\$patch['checkQuery']); - if (!empty(\$existed)) { - \$db->query(\$patch['dropQuery']); - } - } - - foreach (self::\$_tables as \$table) { - \$db->query(\$table['dropQuery']); - } - - self::uninstallCustomized(); - } - - $commentAutoGeneratedEnd - - public static function installCustomized(\$existingAddOn, \$addOnData) - { - // customized install script goes here - } - - public static function uninstallCustomized() - { - // customized uninstall script goes here - } - -} - -EOF; - - return array( - $className, - $contents - ); - } - - public static function getClassName(array $addOn, DevHelper_Config_Base $config) - { - return DevHelper_Generator_File::getClassName($addOn['addon_id'], 'Installer', $config); - } -} diff --git a/library/DevHelper/Generator/Code/Listener.php b/library/DevHelper/Generator/Code/Listener.php deleted file mode 100644 index 2a73270..0000000 --- a/library/DevHelper/Generator/Code/Listener.php +++ /dev/null @@ -1,111 +0,0 @@ -setImportMode(true); - $dw->bulkSet(array( - 'event_id' => 'file_health_check', - 'callback_class' => self::getClassName($addOn, $config), - 'callback_method' => 'file_health_check', - 'addon_id' => $addOn['addon_id'], - )); - return $dw->save(); - } - - return false; - } - - public static function generateLoadClass($realClazz, array $addOn, DevHelper_Config_Base $config) - { - $method = sprintf('load_class_%s', $realClazz); - if (strlen($method) > 50) { - $method = sprintf('load_class_%s', md5($realClazz)); - } - - $existingContents = self::_getClassContents($addOn, $config); - $existingMethods = DevHelper_Helper_Php::extractMethods($existingContents); - if (in_array($method, $existingMethods, true)) { - return $method; - } - - $ourClazz = sprintf('%s_%s', $config->getClassPrefix(), $realClazz); - $methodCode = <<_addOn = $addOn; - $this->_config = $config; - $this->_dataClass = $dataClass; - } - - protected function _generate() - { - $className = $this->_getClassName(); - $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); - $idField = ''; - if (count($this->_dataClass['primaryKey']) == 1) { - $idField = reset($this->_dataClass['primaryKey']); - } - $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - $countFunctionName = self::generateCountDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - - $tableAlias = $this->_dataClass['name']; - if (in_array($tableAlias, array( - 'group', - 'join', - 'order' - ))) { - $tableAlias = '_' . $tableAlias; - } - - $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); - $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); - $conditionFields = DevHelper_Generator_Db::getConditionFields($this->_dataClass['fields']); - - $this->_setClassName($className); - $this->_setBaseClass('XenForo_Model'); - - $this->_addCustomizableMethod("_{$getFunctionName}Customized", 'protected', array( - 'array &$data', - 'array $fetchOptions', - )); - $this->_addCustomizableMethod( - "_prepare{$this->_dataClass['camelCase']}ConditionsCustomized", - 'protected', - array( - 'array &$sqlConditions', - 'array $conditions', - 'array $fetchOptions', - ) - ); - $this->_addCustomizableMethod( - "_prepare{$this->_dataClass['camelCase']}FetchOptionsCustomized", - 'protected', - array( - '&$selectFields', - '&$joinTables', - 'array $fetchOptions', - ) - ); - $this->_addCustomizableMethod( - "_prepare{$this->_dataClass['camelCase']}OrderOptionsCustomized", - 'protected', - array( - 'array &$choices', - 'array &$fetchOptions', - ) - ); - - if (!empty($idField)) { - $this->_addMethod('getList', 'public', array( - '$conditions' => 'array $conditions = array()', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\${$variableNamePlural} = \$this->{$getFunctionName}(\$conditions, \$fetchOptions); -\$list = array(); - -foreach (\${$variableNamePlural} as \$id => \${$variableName}) { - \$list[\$id] = \${$variableName}" . ( - empty($this->_dataClass['title_field']) ? - ("['{$idField}']") : - ( - is_array($this->_dataClass['title_field']) ? - ("['{$this->_dataClass['title_field'][0]}']['{$this->_dataClass['title_field'][1]}']") : - ("['{$this->_dataClass['title_field']}']") - ) - ) . "; -} - -return \$list; - - "); - - $this->_addMethod("get{$this->_dataClass['camelCase']}ById", 'public', array( - '$id', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\${$variableNamePlural} = \$this->{$getFunctionName}(array('{$idField}' => \$id), \$fetchOptions); - -return reset(\${$variableNamePlural}); - - "); - - $this->_addMethod("get{$this->_dataClass['camelCase']}IdsInRange", 'public', array( - '$start', - '$limit', - ), " - -\$db = \$this->_getDb(); - -return \$db->fetchCol(\$db->limit(' - SELECT {$idField} - FROM {$tableName} - WHERE {$idField} > ? - ORDER BY {$idField} -', \$limit), \$start); - - "); - } - - $this->_addMethod($getFunctionName, 'public', array( - '$conditions' => 'array $conditions = array()', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\$whereConditions = \$this->prepare{$this->_dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions); - -\$orderClause = \$this->prepare{$this->_dataClass['camelCase']}OrderOptions(\$fetchOptions); -\$joinOptions = \$this->prepare{$this->_dataClass['camelCase']}FetchOptions(\$fetchOptions); -\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions); - -\${$variableNamePlural} = \$this->" . (!empty($idField) ? "fetchAllKeyed" : "_getDb()->fetchAll") . "(\$this->limitQueryResults(\" - SELECT {$tableAlias}.* - \$joinOptions[selectFields] - FROM `{$tableName}` AS {$tableAlias} - \$joinOptions[joinTables] - WHERE \$whereConditions - \$orderClause - \", \$limitOptions['limit'], \$limitOptions['offset'] -)" . (!empty($idField) ? ", '{$idField}'" : "") . "); - - ", '001'); - - $this->_addMethod($getFunctionName, 'public', array( - '$conditions' => 'array $conditions = array()', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\$this->_{$getFunctionName}Customized(\${$variableNamePlural}, \$fetchOptions); - -return \${$variableNamePlural}; - - ", '999'); - - $this->_addMethod($countFunctionName, 'public', array( - '$conditions' => 'array $conditions = array()', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\$whereConditions = \$this->prepare{$this->_dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions); - -\$orderClause = \$this->prepare{$this->_dataClass['camelCase']}OrderOptions(\$fetchOptions); -\$joinOptions = \$this->prepare{$this->_dataClass['camelCase']}FetchOptions(\$fetchOptions); -\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions); - -return \$this->_getDb()->fetchOne(\" - SELECT COUNT(*) - FROM `{$tableName}` AS {$tableAlias} - \$joinOptions[joinTables] - WHERE \$whereConditions -\"); - - "); - - $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", 'public', array( - '$conditions' => 'array $conditions = array()', - '$fetchOptions' => 'array $fetchOptions = array()', - ), " - -\$sqlConditions = array(); -\$db = \$this->_getDb(); - - "); - - foreach ($conditionFields as $conditionField) { - $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", '', array(), " - -if (isset(\$conditions['{$conditionField}'])) { - if (is_array(\$conditions['{$conditionField}'])) { - if (!empty(\$conditions['{$conditionField}'])) { - // only use IN condition if the array is not empty (nasty!) - \$sqlConditions[] = \"{$tableAlias}.{$conditionField} IN (\" . \$db->quote(\$conditions['{$conditionField}']) . \")\"; - } - } else { - \$sqlConditions[] = \"{$tableAlias}.{$conditionField} = \" . \$db->quote(\$conditions['{$conditionField}']); - } -} - - "); - } - - $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", '', array(), " - -\$this->_prepare{$this->_dataClass['camelCase']}ConditionsCustomized(\$sqlConditions, \$conditions, \$fetchOptions); - -return \$this->getConditionsForClause(\$sqlConditions); - - "); - - $this->_addMethod( - "prepare{$this->_dataClass['camelCase']}FetchOptions", - 'public', - array('$fetchOptions' => 'array $fetchOptions = array()'), - " - -\$selectFields = ''; -\$joinTables = ''; - -\$this->_prepare{$this->_dataClass['camelCase']}FetchOptionsCustomized(\$selectFields, \$joinTables, \$fetchOptions); - -return array( - 'selectFields' => \$selectFields, - 'joinTables' => \$joinTables -); - - " - ); - - $orderChoices = array(); - if (isset($this->_dataClass['fields']['display_order'])) { - if (isset($this->_dataClass['fields']['lft'])) { - $orderChoices['display_order'] = sprintf('%s.lft', $tableAlias); - } else { - $orderChoices['display_order'] = sprintf('%s.display_order', $tableAlias); - } - } - $orderChoices = DevHelper_Generator_File::varExport($orderChoices); - - $this->_addMethod("prepare{$this->_dataClass['camelCase']}OrderOptions", 'public', array( - '$fetchOptions' => 'array $fetchOptions = array()', - '$defaultOrderSql' => '$defaultOrderSql = \'\'', - ), " - -\$choices = {$orderChoices}; - -\$this->_prepare{$this->_dataClass['camelCase']}OrderOptionsCustomized(\$choices, \$fetchOptions); - -return \$this->getOrderByClause(\$choices, \$fetchOptions, \$defaultOrderSql); - - "); - - $this->_generateImageCode(); - $this->_generatePhrasesCode(); - $this->_generateOptionsCode(); - $this->_generateParentCode(); - - return parent::_generate(); - } - - protected function _generateImageCode() - { - $imageField = DevHelper_Generator_Db::getImageField($this->_dataClass['fields']); - if ($imageField === false) { - // no image field... - return ''; - } - - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate image code for %s: too many fields in primary key', - $this->_getClassName() - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); - $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); - $dwClassName = DevHelper_Generator_Code_DataWriter::getClassName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $configPrefix = $this->_config->getPrefix(); - $imagePath = "{$configPrefix}/{$this->_dataClass['camelCase']}"; - $imagePath = strtolower($imagePath); - - $this->_addMethod($getFunctionName, '', array(), " - -// build image urls and make them ready for all the records -\$imageSizes = XenForo_DataWriter::create('{$dwClassName}')->getImageSizes(); -foreach (\${$variableNamePlural} as &\${$variableName}) { - \${$variableName}['images'] = array(); - if (!empty(\${$variableName}['{$imageField}'])) { - foreach (\$imageSizes as \$imageSizeCode => \$imageSize) { - \${$variableName}['images'][\$imageSizeCode] = \$this->getImageUrl(\${$variableName}, \$imageSizeCode); - } - } -} - - ", '100'); - - $this->_addMethod('getImageFilePath', 'public static', array( - sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), - '$size' => '$size = \'l\'', - ), " - -\$internal = self::_getImageInternal(\${$variableName}, \$size); - -if (!empty(\$internal)) { - return XenForo_Helper_File::getExternalDataPath() . \$internal; -} else { - return ''; -} - - "); - - $this->_addMethod('getImageUrl', 'public static', array( - sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), - '$size' => '$size = \'l\'', - ), " - -\$internal = self::_getImageInternal(\${$variableName}, \$size); - -if (!empty(\$internal)) { - return XenForo_Application::\$externalDataUrl . \$internal; -} else { - return ''; -} - - "); - - $this->_addMethod('_getImageInternal', 'protected static', array( - sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), - '$size', - ), " - -if (empty(\${$variableName}['{$idField}']) OR empty(\${$variableName}['{$imageField}'])) { - return ''; -} - -return '/{$imagePath}/' . \${$variableName}['{$idField}'] . '_' . \${$variableName}['{$imageField}'] . strtolower(\$size) . '.jpg'; - - "); - - return true; - } - - protected function _generatePhrasesCode() - { - $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); - $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); - - if (!empty($this->_dataClass['phrases'])) { - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate phrases code for %s: too many fields in primary key', - $this->_getClassName() - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - $statements = ''; - - foreach ($this->_dataClass['phrases'] as $phraseType) { - $getPhraseTitleFunction = self::generateGetPhraseTitleFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass, - $phraseType - ); - $phraseTitlePrefix = DevHelper_Generator_Phrase::getPhraseName( - $this->_addOn, - $this->_config, - $this->_dataClass, - $this->_dataClass['name'] - ) . '_'; - - $this->_addMethod($getPhraseTitleFunction, 'public static', array('$id'), " - -return \"{$phraseTitlePrefix}{\$id}_{$phraseType}\"; - - "); - - $statements .= " '{$phraseType}' => new XenForo_Phrase(self::{$getPhraseTitleFunction}(\${$variableName}['{$idField}'])),\n"; - } - - $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - - $this->_addMethod($getFunctionName, '', array(), " - -// prepare the phrases -foreach (\${$variableNamePlural} as &\${$variableName}) { - \${$variableName}['phrases'] = array( -{$statements} ); -} - - ", '300'); - } - } - - protected function _generateOptionsCode() - { - $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); - $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); - $optionsFields = DevHelper_Generator_Db::getOptionsFields($this->_dataClass['fields']); - - if (!empty($optionsFields)) { - $statements = ''; - - foreach ($optionsFields as $optionsField) { - $statements .= " \${$variableName}['{$optionsField}'] = @unserialize(\${$variableName}['{$optionsField}']);\n"; - $statements .= " if (empty(\${$variableName}['{$optionsField}'])) \${$variableName}['{$optionsField}'] = array();\n"; - } - - $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - - $this->_addMethod($getFunctionName, '', array(), " - -// parse all the options fields -foreach (\${$variableNamePlural} as &\${$variableName}) { -{$statements}} - - ", '400'); - } - } - - protected function _generateParentCode() - { - $parentField = DevHelper_Generator_Db::getParentField($this->_dataClass['name'], $this->_dataClass['fields']); - if ($parentField === false) { - // no parent field... - return; - } - - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf( - 'Cannot generate parent code for %s: too many fields in primary key', - $this->_getClassName() - )); - } - $idField = reset($this->_dataClass['primaryKey']); - - $displayOrderField = false; - $depthField = false; - $lftField = false; - $rgtField = false; - $breadcrumbField = DevHelper_Generator_Db::getBreadcrumbField( - $this->_dataClass['name'], - $this->_dataClass['fields'] - ); - ; - foreach ($this->_dataClass['fields'] as $field) { - if ($field['name'] == 'display_order') { - $displayOrderField = $field['name']; - } elseif ($field['name'] == 'depth') { - $depthField = $field['name']; - } elseif ($field['name'] == 'lft') { - $lftField = $field['name']; - } elseif ($field['name'] == 'rgt') { - $rgtField = $field['name']; - } - } - if (empty($displayOrderField) OR empty($depthField) OR empty($lftField) OR empty($rgtField)) { - // no hierarchy fields - return; - } - - $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); - $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); - $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); - $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); - - $rebuildStructureFunctionName = self::generateRebuildStructureFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - $getStructureChangesFunctionName = '_getStructureChanges'; - $groupByParentsFunctionName = self::generateGroupByParentsFunctionName( - $this->_addOn, - $this->_config, - $this->_dataClass - ); - - $this->_addMethod($rebuildStructureFunctionName, 'public', array(), " - -\$grouped = \$this->{$groupByParentsFunctionName}(\$this->{$getFunctionName}(array(), array('order' => '{$displayOrderField}'))); - -\$db = \$this->_getDb(); -XenForo_Db::beginTransaction(\$db); - -\$changes = \$this->{$getStructureChangesFunctionName}(\$grouped); -foreach (\$changes AS \$id => \$oneChanges) { - \$db->update('{$tableName}', \$oneChanges, '{$idField} = ' . \$db->quote(\$id)); -} - -XenForo_Db::commit(\$db); - -return \$changes; - - "); - - $titleFieldBreadcrumb = ''; - if (!empty($this->_dataClass['title_field']) AND !is_array($this->_dataClass['title_field'])) { - $titleFieldBreadcrumb = "\n '{$this->_dataClass['title_field']}' => " . - "\${$variableName}['{$this->_dataClass['title_field']}'],"; - } - - $breadcrumbStatements = ''; - if (!empty($breadcrumbField)) { - $breadcrumbStatements = "\n if (\${$variableName}['category_breadcrumb'] != \$serializedBreadcrumb) {"; - $breadcrumbStatements .= "\n \$thisChanges['category_breadcrumb'] = \$serializedBreadcrumb;"; - $breadcrumbStatements .= "\n }"; - } - - $this->_addMethod($getStructureChangesFunctionName, 'protected', array( - '$grouped' => 'array $grouped', - '$parentId' => '$parentId = 0', - '$depth' => '$depth = 0', - '$startPosition' => '$startPosition = 1', - 'nextPosition' => '&$nextPosition = 0', - '$breadcrumb' => 'array $breadcrumb = array()', - ), " - -\$nextPosition = \$startPosition; - -if (!isset(\$grouped[\$parentId])) { - return array(); -} - -\$changes = array(); -\$serializedBreadcrumb = serialize(\$breadcrumb); - -foreach (\$grouped[\$parentId] AS \$id => \${$variableName}) { - \$left = \$nextPosition; - \$nextPosition++; - - \$thisBreadcrumb = \$breadcrumb + array( - \$id => array( - '{$idField}' => \$id,{$titleFieldBreadcrumb} - '{$parentField}' => \${$variableName}['{$parentField}'], - ) - ); - - \$changes += \$this->{$getStructureChangesFunctionName}( - \$grouped, - \$id, - \$depth + 1, - \$nextPosition, - \$nextPosition, - \$thisBreadcrumb - ); - - \$thisChanges = array(); - if (\${$variableName}['depth'] != \$depth) { - \$thisChanges['depth'] = \$depth; - } - if (\${$variableName}['lft'] != \$left) { - \$thisChanges['lft'] = \$left; - } - if (\${$variableName}['rgt'] != \$nextPosition) { - \$thisChanges['rgt'] = \$nextPosition; - }{$breadcrumbStatements} - - if (!empty(\$thisChanges)) { - \$changes[\$id] = \$thisChanges; - } - - \$nextPosition++; -} - -return \$changes; - - "); - - $this->_addMethod( - $groupByParentsFunctionName, - 'public', - array(sprintf('$%s', $variableNamePlural) => sprintf('array $%s', $variableNamePlural)), - " - -\$grouped = array(); -foreach (\${$variableNamePlural} AS \${$variableName}) { - \$grouped[\${$variableName}['{$parentField}']][\${$variableName}['{$idField}']] = \${$variableName}; -} - -return \$grouped; - - " - ); - } - - protected function _getClassName() - { - return self::getClassName($this->_addOn, $this->_config, $this->_dataClass); - } - - public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $g = new self($addOn, $config, $dataClass); - - return array( - $g->_getClassName(), - $g->_generate() - ); - } - - public static function getClassName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return DevHelper_Generator_File::getClassName($addOn['addon_id'], 'Model_' . $dataClass['camelCase'], $config); - } - - public static function getVariableName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $variableName = strtolower(substr($dataClass['camelCase'], 0, 1)) . substr($dataClass['camelCase'], 1); - $variableNamePlural = self::getVariableNamePlural($addOn, $config, $dataClass); - - if ($variableName === $variableNamePlural) { - $variableName = '_' . $variableName; - } - - return $variableName; - } - - public static function getVariableNamePlural(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $variableNamePlural = (empty($dataClass['camelCasePlural']) ? ('All' . $dataClass['camelCase']) : ($dataClass['camelCasePlural'])); - - return strtolower(substr($variableNamePlural, 0, 1)) . substr($variableNamePlural, 1); - } - - public static function generateGetDataFunctionName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return 'get' . (empty($dataClass['camelCasePlural']) ? ('All' . $dataClass['camelCase']) : $dataClass['camelCasePlural']); - } - - public static function generateCountDataFunctionName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return 'count' . (empty($dataClass['camelCasePlural']) ? ('All' . $dataClass['camelCase']) : $dataClass['camelCasePlural']); - } - - public static function generateRebuildStructureFunctionName( - array $addOn, - DevHelper_Config_Base $config, - array $dataClass - ) { - return 'rebuild' . $dataClass['camelCase'] . 'Structure'; - } - - public static function generateGroupByParentsFunctionName( - array $addOn, - DevHelper_Config_Base $config, - array $dataClass - ) { - return 'group' . (empty($dataClass['camelCasePlural']) ? ('All' . $dataClass['camelCase']) : $dataClass['camelCasePlural']) . 'ByParents'; - } - - public static function generateGetPhraseTitleFunctionName( - array $addOn, - DevHelper_Config_Base $config, - array $dataClass, - $phraseType - ) { - $camelCase = ucwords(str_replace('_', ' ', $phraseType)); - return 'getPhraseTitleFor' . $camelCase; - } -} diff --git a/library/DevHelper/Generator/Code/RoutePrefixAdmin.php b/library/DevHelper/Generator/Code/RoutePrefixAdmin.php deleted file mode 100755 index 5590228..0000000 --- a/library/DevHelper/Generator/Code/RoutePrefixAdmin.php +++ /dev/null @@ -1,131 +0,0 @@ -_addOn = $addOn; - $this->_config = $config; - $this->_dataClass = $dataClass; - $this->_info = $info; - } - - protected function _generate() - { - $className = $this->_getClassName(); - - if (count($this->_dataClass['primaryKey']) > 1) { - throw new XenForo_Exception(sprintf('Cannot generate %s: too many fields in primary key', $className)); - } - $idField = reset($this->_dataClass['primaryKey']); - - // create the route prefix first - /** @var XenForo_Model_RoutePrefix $routePrefixModel */ - $routePrefixModel = XenForo_Model::create('XenForo_Model_RoutePrefix'); - $existed = $routePrefixModel->getPrefixesByRouteType('admin'); - foreach ($existed as $routePrefix) { - if ($routePrefix['original_prefix'] == $this->_info['routePrefix'] OR $routePrefix['route_class'] == $className) { - // delete duplicated route prefix - $dw = XenForo_DataWriter::create('XenForo_DataWriter_RoutePrefix'); - $dw->setExistingData($routePrefix); - $dw->delete(); - } - } - - eval("class $className {}"); - $dw = XenForo_DataWriter::create('XenForo_DataWriter_RoutePrefix'); - $dw->bulkSet(array( - 'original_prefix' => $this->_info['routePrefix'], - 'route_type' => 'admin', - 'route_class' => $className, - 'build_link' => 'data_only', - 'addon_id' => $this->_addOn['addon_id'], - )); - $dw->save(); - // finished creating our route prefix - - $this->_setClassName($className); - $this->_addInterface('XenForo_Route_Interface'); - - $this->_addMethod('match', 'public', array( - '$routePath', - '$request' => 'Zend_Controller_Request_Http $request', - '$router' => 'XenForo_Router $router', - ), " - -if (in_array(\$routePath, array('add', 'save'))) { - \$action = \$routePath; -} else { - \$action = \$router->resolveActionWithIntegerParam(\$routePath, \$request, '{$idField}'); -} -return \$router->getRouteMatch('{$this->_info['controller']}', \$action, '{$this->_info['majorSection']}'); - - "); - - $this->_addMethod('buildLink', 'public', array( - '$originalPrefix', - '$outputPrefix', - '$action', - '$extension', - '$data', - '$extraParams' => 'array &$extraParams', - ), " - -if (is_array(\$data)) { - return XenForo_Link::buildBasicLinkWithIntegerParam(\$outputPrefix, \$action, \$extension, \$data, '{$idField}'); -} else { - return XenForo_Link::buildBasicLink(\$outputPrefix, \$action, \$extension); -} - - "); - - return parent::_generate(); - } - - protected function _getClassName() - { - return self::getClassName($this->_addOn, $this->_config, $this->_dataClass); - } - - public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass, array $info) - { - $g = new self($addOn, $config, $dataClass, $info); - - return array( - $g->_getClassName(), - $g->_generate() - ); - } - - public static function getClassName(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - return DevHelper_Generator_File::getClassName( - $addOn['addon_id'], - 'Route_PrefixAdmin_' . $dataClass['camelCase'], - $config - ); - } - - public static function getRoutePrefix(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $className = self::getClassName($addOn, $config, $dataClass); - - /** @var XenForo_Model_RoutePrefix $routePrefixModel */ - $routePrefixModel = XenForo_Model::create('XenForo_Model_RoutePrefix'); - $routePrefixes = $routePrefixModel->getPrefixesByAddOnGroupedByRouteType($addOn['addon_id']); - if (!empty($routePrefixes['admin'])) { - foreach ($routePrefixes['admin'] as $routePrefix) { - if ($routePrefix['route_class'] == $className) { - return $routePrefix['original_prefix']; - } - } - } - - return strtolower($addOn['addon_id'] . '-' . $dataClass['name']); - } -} diff --git a/library/DevHelper/Generator/Code/XenForoConfig.php b/library/DevHelper/Generator/Code/XenForoConfig.php deleted file mode 100644 index 16d445f..0000000 --- a/library/DevHelper/Generator/Code/XenForoConfig.php +++ /dev/null @@ -1,55 +0,0 @@ -getRootDir() . '/library/config.php'; - $originalContents = file_get_contents($path); - - $keyParts = explode('.', $key); - $varNamePattern = '#(\n|^)(\\$config'; - foreach ($keyParts as $i => $keyPart) { - // try to match the quote - $varNamePattern .= '\\[([\'"]?)' - // then the key - . preg_quote($keyPart, '#') - // then match the previously matched quote - . '\\' . ($i + 3) . '\\]'; - } - $varNamePattern .= ').+(\n|$)#'; - - $candidates = array(); - $offset = 0; - while (true) { - if (!preg_match($varNamePattern, $originalContents, $matches, PREG_OFFSET_CAPTURE, $offset)) { - break; - } - - $offset = $matches[0][1] + strlen($matches[0][0]); - $candidates[] = $matches; - } - - if (count($candidates) > 1) { - throw new XenForo_Exception(sprintf('count($candidates) = %d', count($candidates))); - } - - $phpStatement = sprintf( - '$config["%s"] = %s;', - implode('"]["', $keyParts), - var_export($value, true) - ); - if (count($candidates) === 1) { - $matches = reset($candidates); - - $replacement = $matches[1][0] . $phpStatement . $matches[5][0]; - $contents = substr_replace($originalContents, $replacement, $matches[0][1], strlen($matches[0][0])); - } else { - $contents = $originalContents . "\n\n" . $phpStatement; - } - - DevHelper_Generator_File::writeFile($path, $contents, true, false); - } -} diff --git a/library/DevHelper/Generator/Db.php b/library/DevHelper/Generator/Db.php deleted file mode 100755 index cad8d7e..0000000 --- a/library/DevHelper/Generator/Db.php +++ /dev/null @@ -1,360 +0,0 @@ -getDataPatches() as $patchTableName => $patchTablePatches) { - if ($patchTableName !== $tableName) { - continue; - } - - foreach ($patchTablePatches as $dataPatch) { - if (!empty($dataPatch['index'])) { - $indexConfigs[$dataPatch['name']] = $dataPatch; - } else { - $fieldConfigs[$dataPatch['name']] = $dataPatch; - } - } - } - - $fields = array(); - foreach ($fieldConfigs as $field) { - $fields[] = "`$field[name]` " . self::_getFieldDefinition($field); - } - $fields = implode("\n ,", $fields); - - if (!empty($dataClass['primaryKey'])) { - $primaryKey = ", PRIMARY KEY (`" . implode('`,`', $dataClass['primaryKey']) . "`)"; - } else { - $primaryKey = ''; - } - - $indeces = array(); - foreach ($indexConfigs as $index) { - $indeces[] = self::_getIndexDefinition($index); - } - $indeces = implode("\n ,", $indeces); - if (!empty($indeces)) { - $indeces = ',' . $indeces; - } - - $sql = <<getPrefix()) !== false - ) { - return $name; - } else { - return 'xf_' . self::getFieldName($config, $name, true); - } - } - - public static function getFieldName(DevHelper_Config_Base $config, $name, $ignoreDash = false) - { - if ($ignoreDash OR strpos($name, '_') === false) { - return strtolower($config->getPrefix() . '_' . $name); - } else { - return strtolower($name); - } - } - - public static function getConditionFields(array $fields) - { - $conditionsFields = array(); - - $intTypes = array( - XenForo_DataWriter::TYPE_BOOLEAN, - XenForo_DataWriter::TYPE_INT, - XenForo_DataWriter::TYPE_UINT, - XenForo_DataWriter::TYPE_UINT_FORCED, - ); - $imageFields = self::getImageFields($fields); - - foreach ($fields as $field) { - if (in_array($field['name'], $imageFields)) { - continue; - } - - if (in_array($field['type'], $intTypes)) { - $conditionsFields[] = $field['name']; - continue; - } - - if ($field['type'] == 'string' AND isset($field['length']) AND $field['length'] <= 255) { - // this is a VARCHAR one - $conditionsFields[] = $field['name']; - continue; - } - } - - return $conditionsFields; - } - - public static function getImageFields(array $fields) - { - $imageFields = array(); - - foreach ($fields as $field) { - if (substr($field['name'], -10) == 'image_date') { - $imageFields[] = $field['name']; - } - } - - return $imageFields; - } - - public static function getImageField(array $fields) - { - $imageFields = self::getImageFields($fields); - - if (count($imageFields) == 1) { - // only return the image field if there is 1 image field - // if there is no image fields or more than 1, simply ignore them all - return $imageFields[0]; - } else { - return false; - } - } - - public static function getOptionsFields(array $fields) - { - $optionsFields = array(); - - foreach ($fields as $field) { - if (substr($field['name'], -8) == '_options' AND $field['type'] == XenForo_DataWriter::TYPE_SERIALIZED) { - $optionsFields[] = $field['name']; - } - } - - return $optionsFields; - } - - public static function getParentField($className, array $fields) - { - $parentFieldNames = array( - sprintf('%s_parent_id', $className), - sprintf('parent_%s_id', $className), - 'parent_id', - ); - - foreach ($fields as $field) { - if (in_array($field['name'], $parentFieldNames)) { - return $field['name']; - } - } - - return false; - } - - public static function getBreadcrumbField($className, array $fields) - { - $breadcrumbFieldNames = array( - sprintf('%s_breadcrumb', $className), - 'breadcrumb', - ); - - foreach ($fields as $field) { - if (in_array($field['name'], $breadcrumbFieldNames)) { - return $field['name']; - } - } - - return false; - } - - public static function getDataTypes() - { - return $types = array( - XenForo_DataWriter::TYPE_BOOLEAN, - XenForo_DataWriter::TYPE_STRING, - XenForo_DataWriter::TYPE_BINARY, - XenForo_DataWriter::TYPE_INT, - XenForo_DataWriter::TYPE_UINT, - XenForo_DataWriter::TYPE_UINT_FORCED, - XenForo_DataWriter::TYPE_FLOAT, - XenForo_DataWriter::TYPE_SERIALIZED, - ); - } - - protected static function _getFieldDefinition($field) - { - switch ($field['type']) { - case XenForo_DataWriter::TYPE_BOOLEAN: - $dbType = 'TINYINT(4) UNSIGNED'; - break; - case XenForo_DataWriter::TYPE_STRING: - if (!isset($field['length']) || $field['length'] > 255) { - $dbType = 'TEXT'; - if (isset($field['length'])) { - if ($field['length'] >= 4294967295) { - $dbType = 'LONGTEXT'; - } elseif ($field['length'] >= 16777215) { - $dbType = 'MEDIUMTEXT'; - } - } - if (isset($field['default'])) { - // BLOB/TEXT column can't have a default value - unset($field['default']); - } - } else { - if (!empty($field['allowedValues'])) { - // ENUM - $dbType = 'ENUM (\'' . implode('\',\'', $field['allowedValues']) . '\')'; - } else { - $dbType = 'VARCHAR(' . $field['length'] . ')'; - } - } - break; - case XenForo_DataWriter::TYPE_BINARY: - if (!isset($field['length']) || $field['length'] > 255) { - $dbType = 'BLOB'; - if (isset($field['length'])) { - if ($field['length'] >= 4294967295) { - $dbType = 'LONGBLOB'; - } elseif ($field['length'] >= 16777215) { - $dbType = 'MEDIUMBLOB'; - } - } - } else { - $dbType = 'VARBINARY(' . $field['length'] . ')'; - } - if (isset($field['default'])) { - // BLOB/TEXT column can't have a default value - unset($field['default']); - } - break; - case XenForo_DataWriter::TYPE_INT: - $dbType = 'INT(11)'; - if (isset($field['length'])) { - if ($field['length'] == 4) { - $dbType = 'TINYINT(' . $field['length'] . ')'; - } - } - break; - case XenForo_DataWriter::TYPE_UINT: - case XenForo_DataWriter::TYPE_UINT_FORCED: - $dbType = 'INT(10) UNSIGNED'; - break; - case XenForo_DataWriter::TYPE_FLOAT: - $dbType = 'FLOAT'; - break; - case 'money': - $dbType = 'DECIMAL(13,4)'; - break; - case XenForo_DataWriter::TYPE_SERIALIZED: - default: - $dbType = 'MEDIUMBLOB'; - if (isset($field['default'])) { - unset($field['default']); - } - // BLOB/TEXT column can't have a default value - break; - } - - return $dbType . (!empty($field['required']) ? ' NOT NULL' : '') . - (isset($field['default']) ? " DEFAULT '{$field['default']}'" : '') . - (!empty($field['autoIncrement']) ? ' AUTO_INCREMENT' : ''); - } - - public static function getIndexTypes() - { - return array( - 'NORMAL', - 'UNIQUE', - 'FULLTEXT', - 'SPATIAL', - ); - } - - protected static function _getIndexDefinition($index) - { - $indexName = $index['name']; - $indexType = strtoupper($index['type']); - - $definition = ($indexType != 'NORMAL' ? ($index['type'] . ' ') : '') - . "INDEX `{$indexName}` (`" . implode('`,`', $index['fields']) . "`)"; - - return $definition; - } -} diff --git a/library/DevHelper/Generator/File.php b/library/DevHelper/Generator/File.php deleted file mode 100755 index 2e5b757..0000000 --- a/library/DevHelper/Generator/File.php +++ /dev/null @@ -1,747 +0,0 @@ -get(sprintf('DevHelper_%sConfigClass', $addOnId)); - if ($addOnId === 'devHelper') { - $className = 'DevHelper_DevHelper_Config'; - } - if (empty($className)) { - $className = sprintf('%s_DevHelper_Config', $addOnId); - } - } else { - if ($config === null) { - throw new XenForo_Exception(sprintf( - '%s requires $config when $subClassName=%s', - __METHOD__, - $subClassName - )); - } - - $className = rtrim(sprintf('%s_%s', $config->getClassPrefix(), $subClassName), '_'); - } - - $classNames[$hash] = $className; - } - - return $classNames[$hash]; - } - - public static function getClassPath($className, DevHelper_Config_Base $config = null) - { - if ($config === null) { - return DevHelper_Autoloader::getDevHelperInstance()->autoloaderClassToFile($className); - } else { - $configClass = get_class($config); - $thisClassParts = explode('_', $className); - $configClassParts = explode('_', $configClass); - - $configClassPath = self::getClassPath($configClass); - $configClassPathParts = explode('/', $configClassPath); - while ($thisClassParts[0] === $configClassParts[0]) { - array_shift($thisClassParts); - array_shift($configClassParts); - } - while (count($configClassParts) > 0) { - array_pop($configClassParts); - array_pop($configClassPathParts); - } - - $path = sprintf('%s/%s.php', implode('/', $configClassPathParts), implode('/', $thisClassParts)); - - return $path; - } - } - - public static function getAddOnIdPath(DevHelper_Config_Base $config) - { - $libraryPath = self::getLibraryPath($config); - $path = $libraryPath . DIRECTORY_SEPARATOR . - str_replace('_', DIRECTORY_SEPARATOR, $config->getClassPrefix()); - - return $path; - } - - public static function getLibraryPath(DevHelper_Config_Base $config) - { - $configClassPath = self::getClassPath(get_class($config)); - $path = $configClassPath; - - do { - if (empty($path)) { - throw new XenForo_Exception(sprintf('Cannot find library path for %s', get_class($config))); - } - $path = dirname($path); - } while (basename($path) !== 'library'); - - return $path; - } - - public static function getAddOnXmlPath( - array $addOn, - array $exportAddOn = null, - DevHelper_Config_Base $config = null - ) { - if ($config === null) { - /** @var DevHelper_Model_Config $configModel */ - $configModel = XenForo_Model::create('DevHelper_Model_Config'); - $config = $configModel->loadAddOnConfig($addOn); - } - - $addOnIdPath = self::getAddOnIdPath($config); - $addOnId = (!empty($exportAddOn) ? $exportAddOn['addon_id'] : $addOn['addon_id']); - - return $addOnIdPath . '/addon-' . $addOnId . '.xml'; - } - - public static function getStyleXmlPath( - array $addOn, - array $style, - DevHelper_Config_Base $config - ) { - $addOnIdPath = self::getAddOnIdPath($config); - - return $addOnIdPath . '/style-' . $style['title'] . '.xml'; - } - - public static function writeFile($path, $contents, $backUp, $isAutoGenerated) - { - $skip = false; - - if (file_exists($path)) { - // existed file - $oldContents = self::fileGetContents($path); - - if ($oldContents == $contents) { - // same content - $skip = true; - } else { - if ($backUp) { - if (strpos($path, 'FileSums.php') !== false) { - // writing FileSums.php - // this file is generated so many times that it's annoying - // so we will skip saving a copy of it... - } else { - copy($path, $path . '.' . XenForo_Application::$time . '.devhelper'); - } - } - - if ($isAutoGenerated AND XenForo_Helper_File::getFileExtension($path) === 'php') { - // different php content - // try to replace the auto generated code only - $startPosOld = strpos($oldContents, self::COMMENT_AUTO_GENERATED_START); - $endPosOld = strpos($oldContents, self::COMMENT_AUTO_GENERATED_END, $startPosOld); - - if ($startPosOld !== false AND $endPosOld !== false AND $endPosOld > $startPosOld) { - // found our comments in old contents - $startPos = strpos($contents, self::COMMENT_AUTO_GENERATED_START); - $endPos = strpos($contents, self::COMMENT_AUTO_GENERATED_END, $startPos); - - if ($startPos !== false AND $endPos !== false AND $endPos > $startPos) { - // found our comments in new contents - $replacement = substr($contents, $startPos, $endPos - $startPos); - $start = $startPosOld; - $length = $endPosOld - $startPosOld; - - $contents = substr_replace($oldContents, $replacement, $start, $length); - } - } - } - } - } - - if (!$skip) { - return self::filePutContents($path, $contents); - } else { - return 'skip'; - } - } - - public static function writeClass($className, $contents, DevHelper_Config_Base $config = null) - { - $path = self::getClassPath($className, $config); - - self::writeFile($path, $contents, true, true); - - if (strpos($className, 'DevHelper_Generated') === false) { - $backupClassName = self::_getBackupClassName($className); - $backupPath = self::getClassPath($backupClassName, $config); - self::writeFile($backupPath . '.devhelper', $contents, false, false); - } - - return $path; - } - - protected static function _getBackupClassName($className) - { - $parts = explode('_', $className); - $prefix = array_shift($parts); - $suffix = implode('_', $parts); - return $prefix . '_DevHelper_Generated_' . $suffix; - } - - public static function fileGetContents($path) - { - if (is_readable($path)) { - $contents = file_get_contents($path); - - return $contents; - } else { - return false; - } - } - - public static function filePutContents($path, $contents) - { - $dir = dirname($path); - XenForo_Helper_File::createDirectory($dir); - if (!is_dir($dir) OR !is_writable($dir)) { - return false; - } - - if (file_put_contents($path, $contents) > 0) { - XenForo_Helper_File::makeWritableByFtpUser($path); - return true; - } - - return false; - } - - public static function generateHashesFile( - array $addOn, - DevHelper_Config_Base $config, - array $directories, - $exportPath, - $rootPath - ) { - $hashes = array(); - $exportPath = rtrim($exportPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $rootPath = rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - - $excludes = $config->getExportExcludes(); - - foreach ($directories as $key => $directory) { - $directory = preg_replace('#^' . preg_quote($rootPath, '#') . '#', $exportPath, $directory); - $directoryHashes = XenForo_Helper_Hash::hashDirectory($directory, array( - '.php', - '.js' - )); - - foreach ($directoryHashes as $filePath => $hash) { - if (strpos($filePath, 'DevHelper') === false AND strpos($filePath, 'FileSums') === false) { - $relative = preg_replace('#^' . preg_quote($exportPath, '#') . '#', '', $filePath); - - $excluded = false; - foreach ($excludes as $exclude) { - if (strpos($relative, $exclude) === 0) { - $excluded = true; - break; - } - } - if ($excluded) { - continue; - } - - $hashes[$relative] = $hash; - } - } - } - - $fileSumsClassName = self::getClassName($addOn['addon_id'], 'FileSums', $config); - $hashesExported = self::varExport($hashes, 2); - $fileSumsContents = "getClassPrefix(); - - $libraryPath = self::getLibraryPath($config); - $rootPath = dirname($libraryPath); - - $list['library'] = self::getAddOnIdPath($config); - if (empty($list['library'])) { - throw new XenForo_Exception(sprintf('`library` not found for %s', $addOn['addon_id'])); - } - - $jsPath = sprintf('%s/js/%s', $rootPath, str_replace('_', DIRECTORY_SEPARATOR, $classPrefix)); - if (is_dir($jsPath)) { - $list['js'] = $jsPath; - } - - $stylesDefaultPath = sprintf( - '%s/styles/default/%s', - $rootPath, - str_replace('_', DIRECTORY_SEPARATOR, $classPrefix) - ); - if (is_dir($stylesDefaultPath)) { - $list['styles_default'] = $stylesDefaultPath; - } - - $exportIncludes = $config->getExportIncludes(); - foreach ($exportIncludes as $exportInclude) { - $exportIncludePath = sprintf('%s/%s', $rootPath, $exportInclude); - - if (file_exists($exportIncludePath)) { - $list[$exportInclude] = $exportIncludePath; - } - } - - // save add-on XML - $xmlPath = self::getAddOnXmlPath($addOn, null, $config); - - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = XenForo_Model::create('XenForo_Model_AddOn'); - $addOnModel->getAddOnXml($addOn)->save($xmlPath); - echo "Exported $xmlPath ($addOn[version_string]/$addOn[version_id])\n"; - DevHelper_Helper_Phrase::parseXmlForPhraseTracking($xmlPath); - - $exportAddOns = $config->getExportAddOns(); - foreach ($exportAddOns as $exportAddOnId) { - $exportAddOn = $addOnModel->getAddOnById($exportAddOnId); - if (empty($exportAddOn)) { - die(sprintf("Could not find add-on %s\n", $exportAddOnId)); - } - - $exportAddOnPath = self::getAddOnXmlPath($addOn, $exportAddOn, $config); - $addOnModel->getAddOnXml($exportAddOn)->save($exportAddOnPath); - echo "Exported $exportAddOnPath ($exportAddOn[version_string]/$exportAddOn[version_id])\n"; - } - - $exportStyles = $config->getExportStyles(); - if (!empty($exportStyles)) { - /** @var XenForo_Model_Style $styleModel */ - $styleModel = $addOnModel->getModelFromCache('XenForo_Model_Style'); - $styles = $styleModel->getAllStyles(); - $exportedStyleCount = 0; - - foreach ($styles as $style) { - if (in_array($style['title'], $exportStyles, true)) { - $stylePath = self::getStyleXmlPath($addOn, $style, $config); - $styleModel->getStyleXml($style)->save($stylePath); - echo "Exported $stylePath\n"; - $exportedStyleCount++; - } - } - - if ($exportedStyleCount < count($exportStyles)) { - die("Not all export styles could be found...\n"); - } - } - - // check for file_health_check event listener - /** @var XenForo_Model_CodeEvent $codeEventModel */ - $codeEventModel = XenForo_Model::create('XenForo_Model_CodeEvent'); - $addOnEventListeners = $codeEventModel->getEventListenersByAddOn($addOn['addon_id']); - $fileHealthCheckFound = false; - foreach ($addOnEventListeners as $addOnEventListener) { - if ($addOnEventListener['event_id'] === 'file_health_check') { - $fileHealthCheckFound = true; - } - - if (!is_callable(array($addOnEventListener['callback_class'], $addOnEventListener['callback_method']))) { - die(sprintf( - "Callback is not callable %s::%s\n", - $addOnEventListener['callback_class'], - $addOnEventListener['callback_method'] - )); - } - } - if (!$fileHealthCheckFound) { - // try to generate the file health check event listener ourselves - if (DevHelper_Generator_Code_Listener::generateFileHealthCheck($addOn, $config)) { - $fileHealthCheckFound = true; - } - } - if (!$fileHealthCheckFound) { - die("No `file_health_check` event listener found.\n"); - } - - if (strpos($exportPath, 'upload') === false) { - $exportPath .= '/upload'; - } - XenForo_Helper_File::createDirectory($exportPath /*, true */); - $exportPath = realpath($exportPath); - $options = array( - 'extensions' => array( - 'php', - 'inc', - 'txt', - 'xml', - 'htm', - 'html', - 'js', - 'css', - 'jpg', - 'jpeg', - 'png', - 'gif', - 'swf', - 'crt', - 'pem', - 'eot', - 'svg', - 'ttf', - 'woff', - 'woff2', - 'otf', - 'md', - ), - 'filenames_lowercase' => array( - 'license', - 'readme', - 'copyright', - '.htaccess', - 'changelog', - 'composer.json', - 'readme.rdoc', - 'version', - ), - 'force' => true, // always force add top level export entries - 'addon_id' => $addOn['addon_id'], - - 'excludes' => array(), - 'excludeRegExs' => array(), - ); - - $excludes = $config->getExportExcludes(); - foreach ($excludes as $exclude) { - if (preg_match('/^#.+#$/', $exclude)) { - $options['excludeRegExs'][] = $exclude; - } else { - $options['excludes'][] = $exclude; - } - } - - // run phpcbf by default if available - // append phpcs=1 in file-export url to run phpcs instead - if (!empty($_REQUEST['phpcbf'])) { - $codingStandardBinary = exec('which phpcbf'); - } else { - $codingStandardBinary = exec('which phpcs'); - if (!empty($codingStandardBinary)) { - $codingStandardBinary .= ' -s'; - } - } - $phpcsOutput = array(); - foreach ($list as $type => $entry) { - if (!empty($codingStandardBinary)) { - exec(sprintf( - '%1$s --standard=%3$s %2$s', - $codingStandardBinary, - escapeshellarg($entry), - escapeshellarg(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpcs.xml') - ), $phpcsOutput); - } - - self::_fileExport($entry, $exportPath, $rootPath, array_merge($options, array('type' => $type))); - } - - $hashesFilePath = self::generateHashesFile($addOn, $config, $list, $exportPath, $rootPath); - self::_fileExport($hashesFilePath, $exportPath, $rootPath, $options); - - // copy one xml copy to the export directory directory - $xmlCopyPath = sprintf('%s/%s', dirname($exportPath), basename($xmlPath)); - if (@copy($xmlPath, $xmlCopyPath)) { - echo "Copied $xmlPath -> $xmlCopyPath\n"; - } else { - echo "Can't cp $xmlPath -> $xmlCopyPath\n"; - } - - echo(implode("\n", $phpcsOutput)); - } - - protected static function _fileExport($entry, &$exportPath, &$rootPath, $options) - { - if (empty($entry)) { - return; - } - - $relativePath = trim(str_replace($rootPath, '', $entry), '/'); - - if (empty($options['force'])) { - if (in_array($relativePath, $options['excludes'])) { - echo "Excluded $relativePath\n"; - return; - } - - foreach ($options['excludeRegExs'] as $excludeRegEx) { - if (preg_match($excludeRegEx, $relativePath)) { - echo "RegExcluded $relativePath\n"; - return; - } - } - - $baseName = basename($relativePath); - switch ($baseName) { - case 'FileSums.php': - case 'upload': - return; - } - } - - if (is_dir($entry)) { - echo "Browsing $relativePath\n"; - - $children = array(); - - $dh = opendir($entry); - while ($child = readdir($dh)) { - if (substr($child, 0, 1) === '.') { - // ignore . (current directory) - // ignore .. (parent directory) - // ignore hidden files (dot files/directories) - continue; - } - - $children[] = $child; - } - - foreach ($children as $child) { - if (!empty($options['force'])) { - $options['force'] = false; - } - // reset `force` option for children - self::_fileExport($entry . '/' . $child, $exportPath, $rootPath, $options); - } - } elseif (is_file($entry)) { - $ext = XenForo_Helper_File::getFileExtension($entry); - if (!empty($options['force']) - || (in_array($ext, $options['extensions']) - && strpos(basename($entry), '.') !== 0) - || in_array(strtolower(basename($entry)), $options['filenames_lowercase']) - ) { - if ($options['addon_id'] == 'devHelper') { - $isDevHelper = (strpos($entry, 'DevHelper/DevHelper') !== false); - } else { - $isDevHelper = (strpos($entry, 'DevHelper') !== false); - } - - if (!$isDevHelper) { - $entryExportPath = $exportPath . '/' . $relativePath; - $entryExportPathOriginal = $entryExportPath; - $contents = null; - - switch ($ext) { - case 'js': - if ($options['type'] === 'js' - && preg_match('#\.min\.js$#', $entry) - ) { - $fullEntry = sprintf( - '%s/full/%s', - dirname($entry), - preg_replace('#\.min\.js$#', '.js', basename($entry)) - ); - if (self::fileGetContents($fullEntry)) { - $contents = ''; - } - } - break; - case 'php': - DevHelper_Helper_ShippableHelper::checkForUpdate($entry); - break; - } - - if ($contents === null) { - $contents = self::fileGetContents($entry); - } - - if (!empty($contents)) { - switch ($ext) { - case 'js': - if ($options['type'] === 'js' - && basename(dirname($entry)) === 'full' - && !preg_match('#\.min\.js$#', $entry) - ) { - $entryExportPath = sprintf( - '%s/%s', - dirname(dirname($entryExportPathOriginal)), - preg_replace('#\.js$#', '.min.js', basename($entry)) - ); - $minPath = DevHelper_Helper_Js::minifyPath($entry); - $contents = self::fileGetContents($minPath); - } - break; - case 'php': - DevHelper_Helper_Phrase::parsePhpForPhraseTracking($relativePath, $contents); - DevHelper_Helper_Xfcp::parsePhpForXfcpClass($relativePath, $contents); - break; - } - - $result = self::writeFile($entryExportPath, $contents, false, false); - } else { - $result = 'empty'; - } - - if ($result === true) { - $result = 'OK'; - if ($entryExportPath !== $entryExportPathOriginal) { - $result = preg_replace( - '#^' . preg_quote($exportPath, '#') . '/#', - '', - $entryExportPath - ); - $result = '-> ' . $result; - } - - echo "Exporting {$relativePath} $result\n"; - } else { - echo "Exporting {$relativePath} $result\n"; - } - } - } - } - } - - public static function varExport($var, $level = 1, $linePrefix = " ", $noKey = false) - { - $output = ''; - - if (is_array($var)) { - $arrayVars = array(); - $multiLine = false; - $keyValueLength = 0; - $allKeysAreInt = true; - foreach ($var as $key => $value) { - $arrayVars[$key] = self::varExport($value, $level + 1, $linePrefix); - if (is_array($value) AND count($value) > 1) { - $multiLine = true; - } - if (strpos($arrayVars[$key], "\n") !== false) { - $multiLine = true; - } - - $keyValueLength += strlen($key); - if (is_array($value)) { - $keyValueLength += strlen(var_export($value, true)); - } else { - $keyValueLength += strlen($value); - } - - if (!is_int($key)) { - $allKeysAreInt = false; - } - } - if ($keyValueLength > 100) { - $multiLine = true; - } - if ($allKeysAreInt) { - $noKey = true; - } - - $output .= 'array('; - $first = true; - foreach ($arrayVars as $key => $str) { - if ($multiLine) { - $output .= "\n" . str_repeat($linePrefix, $level + 1); - } else { - if (!$first) { - $output .= ', '; - } - } - - if (empty($noKey)) { - $output .= var_export($key, true) . ' => '; - } - - $output .= $str; - - if ($multiLine) { - $output .= ','; - } - - $first = false; - } - - if ($multiLine) { - $output .= "\n" . str_repeat($linePrefix, $level); - } - - $output .= ')'; - } elseif (is_object($var) && $var instanceof _DevHelper_Generator_File_Constant) { - $output .= strval($var); - } else { - $tmp = var_export($var, true); - if (strpos($tmp, "\n") !== false) { - $tmp = str_replace("\n", "\n" . str_repeat($linePrefix, $level), $tmp); - } - - $output .= $tmp; - } - - return $output; - } - - public static function varExportConstant($str) - { - return new _DevHelper_Generator_File_Constant($str); - } - - public static function varExportConstantFromArray($value, array $constants) - { - foreach ($constants as $constant) { - if ($value === constant($constant)) { - return self::varExportConstant($constant); - } - } - - return $value; - } -} - -class _DevHelper_Generator_File_Constant -{ - protected $_str = ''; - - public function __construct($str) - { - $this->_str = $str; - } - - public function __toString() - { - return $this->_str; - } -} diff --git a/library/DevHelper/Generator/Phrase.php b/library/DevHelper/Generator/Phrase.php deleted file mode 100755 index a9e6ff4..0000000 --- a/library/DevHelper/Generator/Phrase.php +++ /dev/null @@ -1,64 +0,0 @@ -bulkSet(array( - 'title' => $title, - 'phrase_text' => $phraseText, - 'language_id' => 0, - 'global_cache' => 0, - 'addon_id' => $addOn['addon_id'], - )); - $writer->updateVersionId(); - $writer->save(); - - return true; - } - - public static function generatePhraseAutoCamelCaseStyle( - array $addOn, - DevHelper_Config_Base $config, - array $dataClass, - $dashText - ) { - $camelCase = ucwords(str_replace('_', ' ', $dashText)); - $title = self::getPhraseName($addOn, $config, $dataClass, $dashText); - self::generatePhrase($addOn, $title, $camelCase); - - return $title; - } - - public static function checkPhraseExists($title) - { - $info = self::_getPhraseModel()->getPhrasesInLanguageByTitles(array($title), 0); - - return !empty($info); - } - - /** - * @return XenForo_Model_Phrase - */ - protected static function _getPhraseModel() - { - /** @var XenForo_Model_Phrase $model */ - static $model = null; - - if ($model === null) { - $model = XenForo_Model::create('XenForo_Model_Phrase'); - } - - return $model; - } -} diff --git a/library/DevHelper/Generator/Template.php b/library/DevHelper/Generator/Template.php deleted file mode 100755 index 0a512bc..0000000 --- a/library/DevHelper/Generator/Template.php +++ /dev/null @@ -1,70 +0,0 @@ -keyPropertiesByName($propertyModel->getEffectiveStylePropertiesInStyle(-1)); - $propertyChanges = $propertyModel->translateEditorPropertiesToArray($template, $template, $properties); - - $writer = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate'); - $writer->bulkSet(array( - 'title' => $title, - 'template' => $template, - 'addon_id' => $addOn['addon_id'], - )); - - try { - $writer->save(); - } catch (Exception $ex) { - throw new XenForo_Exception("Exception creating template $title: " . - $ex->getMessage() . '
' . htmlentities($template) . '
'); - } - - $propertyModel->saveStylePropertiesInStyleFromTemplate(-1, $propertyChanges, $properties); - - return true; - } - - public static function checkAdminTemplateExists($title) - { - $info = self::_getAdminTemplateModel()->getAdminTemplateByTitle($title); - - return !empty($info); - } - - /** - * @return XenForo_Model_AdminTemplate - */ - protected static function _getAdminTemplateModel() - { - /** @var XenForo_Model_AdminTemplate $model */ - static $model = null; - - if ($model === null) { - $model = XenForo_Model::create('XenForo_Model_AdminTemplate'); - } - - return $model; - } - - /** - * @return XenForo_Model_StyleProperty - */ - protected static function _getStylePropertyModel() - { - /** @noinspection PhpIncompatibleReturnTypeInspection */ - return self::_getAdminTemplateModel()->getModelFromCache('XenForo_Model_StyleProperty'); - } -} diff --git a/library/DevHelper/Generator/phpcs.xml b/library/DevHelper/Generator/phpcs.xml deleted file mode 100644 index 23c95fb..0000000 --- a/library/DevHelper/Generator/phpcs.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - */CodeMirror/ - */DevHelper/Generated/ - */Lib/ - */ShippableHelper/ - */tests/ - *.min.js - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/library/DevHelper/Helper/File.php b/library/DevHelper/Helper/File.php deleted file mode 100644 index 6fdb444..0000000 --- a/library/DevHelper/Helper/File.php +++ /dev/null @@ -1,34 +0,0 @@ - static::FIND_XML_IF_PATHS_COUNT_LESS_THAN) { - return ''; - } - - $subPaths = array(); - foreach ($paths as $path) { - if (!is_dir($path)) { - continue; - } - - $contentPaths = glob(sprintf('%s/*', rtrim($path, '/'))); - foreach ($contentPaths as $contentPath) { - if (is_dir($contentPath)) { - $subPaths[] = $contentPath . '/'; - } else { - $ext = XenForo_Helper_File::getFileExtension($contentPath); - if ($ext === 'xml') { - return $contentPath; - } - } - } - } - - return static::findXml($subPaths); - } -} diff --git a/library/DevHelper/Helper/Js.php b/library/DevHelper/Helper/Js.php deleted file mode 100644 index 4d985f0..0000000 --- a/library/DevHelper/Helper/Js.php +++ /dev/null @@ -1,83 +0,0 @@ -&1', - escapeshellarg($fullPath), - escapeshellarg($minPath), - escapeshellarg(sprintf( - 'root=full,base="%1$s",url=%2$s.map', - dirname($fullPath), - basename($minPath) - )) - ); - - exec($command, $uglifyOutput, $uglifyResult); - - if (!file_exists($minPath) || $uglifyResult !== 0) { - echo(sprintf("%s: %s\n%s -> %d
\n", __METHOD__, $fullPath, $command, $uglifyResult)); - var_export($uglifyOutput); - exit($uglifyResult); - } - - return $minPath; - } - - public static function processJsFiles(array $jsFiles) - { - foreach ($jsFiles as $path) { - if (strpos($path, 'js') !== 0) { - // ignore non js files - continue; - } - - if (strpos($path, 'js/xenforo/') === 0) { - // ignore xenforo files - continue; - } - - if (!preg_match('#\.min\.js$#', $path)) { - // ignore non .min.js files - continue; - } - - /** @var XenForo_Application $application */ - $application = XenForo_Application::getInstance(); - $fullPath = sprintf( - '%s/%s/full/%s', - $application->getRootDir(), - dirname($path), - preg_replace('#\.min\.js$#', '.js', basename($path)) - ); - if (!empty($_SERVER['DEVHELPER_ROUTER_PHP'])) { - $fullPath = DevHelper_Router::locate($fullPath); - } - - if (file_exists($fullPath)) { - static::minifyPath($fullPath); - } - } - } -} diff --git a/library/DevHelper/Helper/Php.php b/library/DevHelper/Helper/Php.php deleted file mode 100644 index bd2b40e..0000000 --- a/library/DevHelper/Helper/Php.php +++ /dev/null @@ -1,107 +0,0 @@ -= $phpLength) { - // unclosed string - return false; - } - $next = substr($php, $innerOffset, 1); - } elseif ($next === $operator) { - // found another instance of the operator, end of string - $offset = $innerOffset; - return $string; - } - - $string .= $next; - $innerOffset++; - if ($innerOffset >= $phpLength) { - // unclosed string - return false; - } - } - break; - } - - return false; - } - - public static function extractMethods($php) - { - $methods = array(); - - $offset = 0; - while (true) { - if (preg_match( - '#(public|protected|private|static|\s)*' - . 'function\s+(?[a-zA-Z0-9_]+)\s*\([^\)]*\)\s*{#', - $php, - $matches, - PREG_OFFSET_CAPTURE, - $offset - )) { - $methods[] = $matches['method'][0]; - $offset = $matches[0][1] + strlen($matches[0][0]); - } else { - break; - } - } - - return $methods; - } - - public static function appendMethod($php, $methodCode) - { - $lines = explode("\n", $php); - $backUp = array(); - - while (true) { - $lastLine = array_pop($lines); - $pos = strrpos($lastLine, '}'); - if ($pos === false) { - $backUp[] = $lastLine; - continue; - } - - $prev = substr($lastLine, 0, $pos); - $lines[] = $prev; - - $indent = ' '; - if (preg_match('#^(?\s+)([^\s]|$)#', $prev, $matches)) { - $indent .= $matches['indent']; - } - - $methodCodeLines = explode("\n", $methodCode); - foreach ($methodCodeLines as $methodCodeLine) { - $lines[] = $indent . $methodCodeLine; - } - - $lines[] = substr($lastLine, $pos); - break; - } - - $contents = implode("\n", $lines); - if (!empty($backUp)) { - $contents .= "\n" . implode("\n", array_reverse($backUp)); - } - return $contents; - } -} diff --git a/library/DevHelper/Helper/Phrase.php b/library/DevHelper/Helper/Phrase.php deleted file mode 100644 index d131ba4..0000000 --- a/library/DevHelper/Helper/Phrase.php +++ /dev/null @@ -1,149 +0,0 @@ -{$phrase['title']}\n"; - } else { - $usedPhraseTitles[] = $phrase['title']; - } - } - - foreach ($foundPhraseTitles as $phraseTitle) { - if (!in_array($phraseTitle, $usedPhraseTitles)) { - $foundButUnusedPhraseTitles[] = $phraseTitle; - } - } - if (!empty($foundButUnusedPhraseTitles)) { - $foundButUnusedPhrases = $phraseModel->getPhrasesInLanguageByTitles($foundButUnusedPhraseTitles); - foreach ($foundButUnusedPhraseTitles as $phraseTitle) { - $good = true; - - if (empty($foundButUnusedPhrases[$phraseTitle])) { - echo "Phrase not found: {$phraseTitle}\n"; - $good = false; - } - - if ($good) { - $foundButUnusedPhrase = $foundButUnusedPhrases[$phraseTitle]; - if (!empty($foundButUnusedPhrase['addon_id']) AND $foundButUnusedPhrase['addon_id'] !== 'XenForo') { - echo "Phrase from another add-on: {$phraseTitle} ({$foundButUnusedPhrase['addon_id']})\n"; - $good = false; - } - } - - if (!$good) { - $phraseUsages = self::getPhraseUsages($phraseTitle); - foreach ($phraseUsages as $phraseUsagePath => $phraseUsageLine) { - echo " Used in {$phraseUsagePath}:{$phraseUsageLine}\n"; - } - } - } - } - } - - public static function getFoundPhraseTitles() - { - return array_keys(self::$_foundPhraseTitles); - } - - public static function getPhraseUsages($phraseTitle) - { - if (isset(self::$_foundPhraseTitles[$phraseTitle])) { - return self::$_foundPhraseTitles[$phraseTitle]; - } else { - return array(); - } - } - - public static function parsePhpForPhraseTracking($path, $contents) - { - if (self::$_lookingForPhraseTitles == false) { - return; - } - - if (strpos($path, 'library/DevHelper/') === 0) { - return; - } - - $offset = 0; - $newXenForoPhrase = 'new XenForo_Phrase('; - while (true) { - $strPos = strpos($contents, $newXenForoPhrase, $offset); - - if ($strPos !== false) { - $offset = $strPos + strlen($newXenForoPhrase); - $phraseTitle = DevHelper_Helper_Php::extractString($contents, $offset); - - if (is_string($phraseTitle)) { - self::$_foundPhraseTitles[$phraseTitle][$path] = substr_count(substr($contents, 0, $offset), "\n"); - } else { - continue; - } - } else { - break; - } - } - } - - public static function parseXmlForPhraseTracking($path) - { - if (self::$_lookingForPhraseTitles == false) { - return; - } - - $contents = file_get_contents($path); - - $offset = 0; - while (true) { - if (preg_match( - '/{xen:phrase\s+(?[^,}]+)(,|})/', - $contents, - $matches, - PREG_OFFSET_CAPTURE, - $offset - )) { - $phraseTitle = $matches['title'][0]; - self::$_foundPhraseTitles[$phraseTitle][$path] = substr_count(substr($contents, 0, $offset), "\n"); - $offset = $matches[0][1] + strlen($matches[0][0]); - } else { - break; - } - } - } -} diff --git a/library/DevHelper/Helper/ShippableHelper.php b/library/DevHelper/Helper/ShippableHelper.php deleted file mode 100644 index 2d87e64..0000000 --- a/library/DevHelper/Helper/ShippableHelper.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -class DevHelper_Helper_ShippableHelper -{ - public static function getVersionId($class, $path, $contents) - { - if (XenForo_Application::debugMode()) { - return filemtime($path); - } - - if (preg_match( - '#/\*\*.+?Class ' - . preg_quote($class, '#') - . '.+?@version (?<version>\d+)\s.+?\*/#s', - $contents, - $matches - )) { - return intval($matches['version']); - } else { - return false; - } - } - - public static function update($targetClass, $targetPath, $sourceClass, $sourcesContents) - { - $targetContents = str_replace($sourceClass, $targetClass, $sourcesContents); - - $php = '<?php'; - $pos = utf8_strpos($targetContents, $php); - if ($pos !== false) { - $replacement = sprintf("%s\n\n// updated by %s at %s", $php, __CLASS__, date('c')); - $targetContents = utf8_substr_replace($targetContents, $replacement, $pos, utf8_strlen($php)); - } - - $classPrefix = substr($targetClass, 0, strpos($targetClass, 'ShippableHelper_')); - $offset = 0; - while (true) { - if (!preg_match( - '#DevHelper_Helper_ShippableHelper_[a-zA-Z_]+#', - $targetContents, - $matches, - PREG_OFFSET_CAPTURE, - $offset - ) - ) { - break; - } - - $siblingSourceClass = $matches[0][0]; - $offset = $matches[0][1]; - $siblingTargetClass = str_replace('DevHelper_Helper_', $classPrefix, $siblingSourceClass); - $targetContents = substr_replace( - $targetContents, - $siblingTargetClass, - $offset, - strlen($siblingSourceClass) - ); - - class_exists($siblingTargetClass); - - $offset += 1; - } - - $targetContents = preg_replace( - '#\* @version \d+\s*\n#', - '$0 * @see ' . $sourceClass . "\n", - $targetContents, - -1, - $count - ); - - return DevHelper_Generator_File::filePutContents($targetPath, $targetContents); - } - - public static function checkForUpdate($path) - { - if (strpos($path, '/ShippableHelper/') !== false) { - $contents = DevHelper_Generator_File::fileGetContents($path); - - if (preg_match('#class\s(?<class>[^\s]+_ShippableHelper_[^\s]+)\s#', $contents, $matches)) { - class_exists($matches['class']); - } - } - } -} diff --git a/library/DevHelper/Helper/ShippableHelper/Crypt.php b/library/DevHelper/Helper/ShippableHelper/Crypt.php deleted file mode 100644 index bf7e9d5..0000000 --- a/library/DevHelper/Helper/ShippableHelper/Crypt.php +++ /dev/null @@ -1,153 +0,0 @@ -<?php - -/** - * Class DevHelper_Helper_ShippableHelper_Crypt - * @version 3 - */ -class DevHelper_Helper_ShippableHelper_Crypt -{ - const ALGO_AES_128 = 'aes128'; - const ALGO_AES_256 = 'aes256'; - - const OPENSSL_METHOD_AES128 = 'aes-128-ecb'; - const OPENSSL_METHOD_AES256 = 'aes-256-cbc'; - - public static function encrypt($data, $key = null, $algo = null) - { - if ($key === null) { - $key = XenForo_Application::getConfig()->get('globalSalt'); - } - - switch ($algo) { - case self::ALGO_AES_128: - return self::_aes128_encrypt($data, $key); - default: - case self::ALGO_AES_256: - return self::_aes256_encrypt($data, $key); - } - } - - public static function decrypt($data, $key = null, $algo = null) - { - if ($key === null) { - $key = XenForo_Application::getConfig()->get('globalSalt'); - } - - if ($algo === null) { - if (substr($data, 0, strlen(self::ALGO_AES_256)) === self::ALGO_AES_256) { - $algo = self::ALGO_AES_256; - } else { - $algo = self::ALGO_AES_128; - } - } - - switch ($algo) { - case self::ALGO_AES_128: - return self::_aes128_decrypt($data, $key); - default: - case self::ALGO_AES_256: - return self::_aes256_decrypt($data, $key); - } - } - - /** - * Legacy AES 128 encryption. - * Supports both OpenSSL and mcrypt. - * Warning: This method is insecure and potentially dangerous, should be avoided for new application. - * - * @param string $data - * @param string $key - * @return string - */ - protected static function _aes128_encrypt($data, $key) - { - if (function_exists('openssl_encrypt')) { - $key = md5($key, true); - return openssl_encrypt($data, self::OPENSSL_METHOD_AES128, $key, OPENSSL_RAW_DATA); - } - - if (function_exists('mcrypt_encrypt')) { - $key = md5($key, true); - $padding = 16 - (strlen($data) % 16); - $data .= str_repeat(chr($padding), $padding); - /** @noinspection PhpDeprecationInspection */ - return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB); - } - - return $data; - } - - /** - * Legacy AES 128 decryption. - * Supports both OpenSSL and mcrypt. - * Warning: This method is insecure and potentially dangerous, should be avoided for new application. - * - * @param string $data - * @param string $key - * @return string - */ - protected static function _aes128_decrypt($data, $key) - { - if (function_exists('openssl_decrypt')) { - $key = md5($key, true); - return openssl_decrypt($data, self::OPENSSL_METHOD_AES128, $key, OPENSSL_RAW_DATA); - } - - if (function_exists('mcrypt_decrypt')) { - $key = md5($key, true); - /** @noinspection PhpDeprecationInspection */ - $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB); - $padding = ord($data[strlen($data) - 1]); - return substr($data, 0, -$padding); - } - - return $data; - } - - /** - * Secure AES 256 encryption. - * This method only supports OpenSSL (unlike the AES 128 variant which also supports mcrypt). - * - * @param string $data - * @param string $key - * @return string - */ - protected static function _aes256_encrypt($data, $key) - { - if (function_exists('mb_substr') && function_exists('openssl_encrypt')) { - $ivLength = openssl_cipher_iv_length(self::OPENSSL_METHOD_AES256); - $iv = openssl_random_pseudo_bytes($ivLength); - $encrypted = openssl_encrypt($data, self::OPENSSL_METHOD_AES256, $key, OPENSSL_RAW_DATA, $iv); - - return self::ALGO_AES_256 . $iv . $encrypted; - } - - return $data; - } - - /** - * Secure AES 256 decryption. - * This method only supports OpenSSL (unlike the AES 128 variant which also supports mcrypt). - * - * @param string $data - * @param string $key - * @return string - */ - protected static function _aes256_decrypt($data, $key) - { - if (function_exists('mb_substr') && function_exists('openssl_encrypt')) { - $prefixLength = mb_strlen(self::ALGO_AES_256, '8bit'); - $prefix = mb_substr($data, 0, $prefixLength); - if ($prefix === self::ALGO_AES_256) { - $ivLength = openssl_cipher_iv_length(self::OPENSSL_METHOD_AES256); - $iv = mb_substr($data, $prefixLength, $ivLength, '8bit'); - $encrypted = mb_substr($data, $prefixLength + $ivLength, null, '8bit'); - - return openssl_decrypt($encrypted, self::OPENSSL_METHOD_AES256, $key, OPENSSL_RAW_DATA, $iv); - } - } - - return $data; - } - -} diff --git a/library/DevHelper/Helper/ShippableHelper/DateTime.php b/library/DevHelper/Helper/ShippableHelper/DateTime.php deleted file mode 100644 index 433aa65..0000000 --- a/library/DevHelper/Helper/ShippableHelper/DateTime.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -/** - * Class DevHelper_Helper_ShippableHelper_DateTime - * @version 3 - */ -class DevHelper_Helper_ShippableHelper_DateTime -{ - public static function tzOffsetToName($offset, $isDst = null) - { - if ($isDst === null) { - $isDst = date('I'); - } - - $zone = timezone_name_from_abbr('', $offset, $isDst); - - if ($zone === false) { - foreach (timezone_abbreviations_list() as $abbr) { - foreach ($abbr as $city) { - if ((bool)$city['dst'] === (bool)$isDst && - strlen($city['timezone_id']) > 0 && - $city['offset'] == $offset - ) { - $zone = $city['timezone_id']; - break; - } - } - - if ($zone !== false) { - break; - } - } - } - - return $zone; - } - - /** - * Get Unix timestamp in GMT for inputted date values. - * - * @param int|array $year in user timezone - * @param int $month in user timezone - * @param int $day in user timezone - * @param int $hour in user timezone - * @param int $minute in user timezone - * @param int $second in user timezone - * @param int|null $offset custom offset to override user's - * - * @return int timestamp in GMT - */ - public static function gmmktime($year, $month = 0, $day = 0, $hour = 0, $minute = 0, $second = 0, $offset = null) - { - if (is_array($year)) { - $args = func_get_args(); - if (count($args) !== 1) { - return 0; - } - - $values = $year; - $year = 0; - foreach (array('year', 'month', 'day', 'hour', 'minute', 'second', 'offset') as $key) { - if (isset($values[$key]) - && is_int($values[$key]) - ) { - $$key = intval($values[$key]); - } - } - } - - $timestamp = gmmktime($hour, $minute, $second, $month, $day, $year); - - if ($offset === null) { - $offset = XenForo_Locale::getTimeZoneOffset(); - } - - return $timestamp - $offset; - } - - /** - * Get timezone offset by string or object - * - * @param string|DateTimeZone $timeZoneString String time zone to override user timezone - * @return int - */ - public static function getTimeZoneOffset($timeZoneString) - { - $dt = new DateTime('@' . XenForo_Application::$time); - - if ($timeZoneString instanceof DateTimeZone) { - $timeZone = $timeZoneString; - } else { - $timeZone = new DateTimeZone($timeZoneString); - } - $dt->setTimezone($timeZone); - - return $dt->getOffset(); - } - -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/Html.php b/library/DevHelper/Helper/ShippableHelper/Html.php deleted file mode 100644 index 5f65eb9..0000000 --- a/library/DevHelper/Helper/ShippableHelper/Html.php +++ /dev/null @@ -1,399 +0,0 @@ -<?php - -/** - * Class DevHelper_Helper_ShippableHelper_Html - * @version 18 - */ -class DevHelper_Helper_ShippableHelper_Html -{ - public static function viewSnippet($string, array $params) - { - return self::snippet($string, 0, $params); - } - - public static function preSnippet(array &$message, XenForo_BbCode_Parser $parser, array $options = array()) - { - $options = array_merge(array( - 'previewBreakBbCode' => 'prbreak', - 'messageKey' => 'message', - ), $options); - - $previewFound = false; - $tagOpen = ''; - $tagClose = ''; - - if (!empty($options['previewBreakBbCode'])) { - $textRef =& $message[$options['messageKey']]; - $tagOpen = '[' . $options['previewBreakBbCode'] . ']'; - $posOpen = stripos($textRef, $tagOpen); - if ($posOpen !== false) { - $tagClose = '[/' . $options['previewBreakBbCode'] . ']'; - $posClose = stripos($textRef, $tagClose, $posOpen); - if ($posClose !== false) { - $previewFound = true; - $previewTextOffset = $posOpen + strlen($tagOpen); - $previewTextLength = $posClose - $posOpen - strlen($tagOpen); - - if ($previewTextLength > 0) { - $textRef = substr($textRef, $previewTextOffset, $previewTextLength); - - } else { - $textRef = substr($textRef, 0, $posOpen); - } - } - } - } - - $messageHtml = XenForo_ViewPublic_Helper_Message::getBbCodeWrapper( - $message, $parser, $options); - - if ($previewFound) { - $messageHtml = sprintf('%s%s%s', $tagOpen, $messageHtml, $tagClose); - } - - return $messageHtml; - } - - /** - * @param string $string - * @param int $maxLength - * @param array $options - * - * @return string - */ - public static function snippet($string, $maxLength = 0, array $options = array()) - { - $options = array_merge(array( - 'context' => '', - 'ellipsis' => '…', - 'fromStart' => true, - 'previewBreakBbCode' => 'prbreak', - 'processImage' => true, - 'processLink' => true, - 'processFrame' => true, - 'processScript' => true, - 'replacements' => array(), - 'stripImage' => false, - 'stripLink' => false, - 'stripFrame' => false, - 'stripScript' => false, - 'stripSpacing' => true, - - // WARNING: options below are for internal usage only - '_isPreview' => false, - ), $options); - if (!isset($options['maxLength'])) { - $options['maxLength'] = $maxLength; - } - - self::snippetPreProcess($string, $options); - if (!empty($options['_isPreview'])) { - $snippet = $string; - } else { - $snippet = self::snippetCallHelper($string, $options); - self::snippetFixBrokenHtml($snippet, $options); - } - - if (!empty($options['context'])) { - self::snippetOnContext($snippet, $options['context']); - } - - if ($snippet === '') { - $plainTextString = utf8_trim(strip_tags($string)); - if ($plainTextString !== '') { - $snippet = self::snippetCallHelper($plainTextString, $options); - } - } - - self::snippetPostProcess($snippet, $options); - - return $snippet; - } - - public static function snippetPreProcess(&$string, array &$options) - { - if (!empty($options['previewBreakBbCode']) - && preg_match(sprintf('#\[%1$s\](?<' . 'preview>.*)\[/%1$s\]#si', - preg_quote($options['previewBreakBbCode'], '#')), - $string, $matches, PREG_OFFSET_CAPTURE) - ) { - // preview break bbcode found - if (!empty($matches['preview'][0])) { - // preview text specified, use it directly - $string = $matches['preview'][0]; - $options['maxLength'] = 0; - $options['_isPreview'] = true; - } else { - // use content before the found bbcode to continue - $string = substr($string, 0, $matches[0][1]); - $options['maxLength'] = 0; - } - } - - $string = str_replace("\n", ' ', $string); - $string = preg_replace('#<br\s?\/?>#', "\n", $string); - $string = str_replace('​', '', $string); - - if (!empty($options['_isPreview'])) { - return; - } - - $replacementsRef =& $options['replacements']; - $replacementTags = array(); - if (!!$options['processImage'] && !$options['stripImage']) { - $replacementTags[] = 'img'; - } - if (!!$options['processLink'] && !$options['stripLink']) { - $replacementTags[] = 'a'; - } - if (!!$options['processFrame'] && !$options['stripFrame']) { - $replacementTags[] = 'iframe'; - } - if (!!$options['processScript'] && !$options['stripScript']) { - $replacementTags[] = 'script'; - } - if (count($replacementTags) > 0) { - $replacementOffset = 0; - $replacementRegEx = sprintf('#<(%s)(\s[^>]*)?>.*?</\\1>#i', implode('|', $replacementTags)); - while (true) { - if (!preg_match($replacementRegEx, $string, - $replacementMatches, PREG_OFFSET_CAPTURE, $replacementOffset) - ) { - break; - } - $replacement = array( - 'original' => $replacementMatches[0][0], - 'replacement' => sprintf('<br data-replacement-id="%d" />', count($replacementsRef)), - ); - $replacementsRef[] = $replacement; - $string = str_replace($replacement['original'], $replacement['replacement'], $string); - $replacementOffset = $replacementMatches[0][1] + 1; - } - } - - if (!!$options['stripImage']) { - $string = preg_replace('#<img[^>]+/>#', '', $string); - } - if (!!$options['stripLink']) { - $string = preg_replace('#<a[^>]+>(.+?)</a>#', '$1', $string); - } - if (!!$options['stripFrame']) { - $string = preg_replace('#<iframe[^>]+></iframe>#', '', $string); - } - if (!!$options['stripScript']) { - $string = preg_replace('#<script[^>]+>.*?</script>#', '', $string); - } - if (!!$options['stripSpacing']) { - $string = preg_replace('#(\n\s*)+#', "\n", $string); - } - } - - public static function snippetCallHelper($string, array &$options) - { - $snippet = XenForo_Template_Helper_Core::callHelper('snippet', array($string, $options['maxLength'], $options)); - - // TODO: find better way to avoid having to call this to reset snippet - $snippet = htmlspecialchars_decode($snippet); - $snippet = preg_replace('#\.\.\.\z#', '', $snippet); - - return $snippet; - } - - public static function snippetFixBrokenHtml(&$snippet, array &$options) - { - $offset = 0; - $stack = array(); - while (true) { - $startPos = utf8_strpos($snippet, '<', $offset); - if ($startPos !== false) { - $endPos = utf8_strpos($snippet, '>', $startPos); - if ($endPos === false) { - // we found a partial open tag, best to delete the whole thing - $snippet = utf8_substr($snippet, 0, $startPos); - break; - } - - $foundLength = $endPos - $startPos - 1; - $found = utf8_substr($snippet, $startPos + 1, $foundLength); - $offset = $endPos; - - if (preg_match('#^(?<closing>/?)(?<tag>\w+)#', $found, $matches)) { - $tag = $matches['tag']; - $isClosing = !empty($matches['closing']); - $isSelfClosing = (!$isClosing && (utf8_substr($found, $foundLength - 1, 1) === '/')); - - if ($isClosing) { - $lastInStack = null; - $lastInStackTag = null; - if (count($stack) > 0) { - $lastInStack = array_pop($stack); - $lastInStackTag = $lastInStack['tag']; - } - - if ($lastInStackTag !== $tag) { - // found tag does not match the one in stack - $replacement = ''; - - // first we have to close the one in stack - if ($lastInStackTag !== null) { - $replacement .= sprintf('</%s>', $tag); - } - - // then we have to self close the found tag - $replacement .= utf8_substr($snippet, $startPos, $endPos - $startPos - 1); - $replacement .= '/>'; - - // do the replacement - $snippet = utf8_substr_replace($snippet, $replacement, $startPos, $endPos - $startPos); - $offset = $startPos + utf8_strlen($snippet); - } - } elseif ($isSelfClosing) { - // do nothing - } else { - // is opening tag - $stack[] = array('tag' => $tag, 'offset' => $startPos, 'till' => $endPos); - } - } - } else { - break; - } - } - - // close any remaining tags - while (!empty($stack)) { - $stackItem = array_pop($stack); - if (utf8_strlen($snippet) === $stackItem['till'] + 1) { - // the latest tag is empty, delete it - $snippet = utf8_substr($snippet, 0, $stackItem['offset']); - continue; - } - - self::snippetAppendEllipsis($snippet, $options); - $snippet .= sprintf('</%s>', $stackItem['tag']); - } - } - - public static function snippetAppendEllipsis(&$snippet, array &$options) - { - if (empty($options['ellipsis'])) { - return; - } - - if (!preg_match('#<\/?(div|iframe|img|li|ol|p|script|ul)[^>]*>\z#', $snippet)) { - $snippet .= $options['ellipsis']; - $options['ellipsis'] = ''; - } - } - - public static function snippetOnContext(&$snippet, $context) - { - switch ($context) { - case 'link': - if (strpos($snippet, '<a ') !== false) { - $snippet = ''; - } - break; - } - } - - public static function snippetPostProcess(&$snippet, array &$options) - { - // strip all empty body tags - $snippetBinaryLength = 0; - while (strlen($snippet) !== $snippetBinaryLength) { - $snippetBinaryLength = strlen($snippet); - $snippet = preg_replace('#<(\w+)(\s[^>]+)?>\s*<\/\\1>#', '', $snippet); - } - - // restore replacements - foreach ($options['replacements'] as $replacement) { - $snippet = str_replace($replacement['replacement'], $replacement['original'], $snippet); - } - - // remove invisible characters - $snippet = utf8_trim($snippet); - - // restore line breaks - $snippet = nl2br($snippet); - - self::snippetAppendEllipsis($snippet, $options); - - $snippet = utf8_trim($snippet); - } - - public static function stripFont($html) - { - $html = preg_replace('#(<[^>]+)( style="[^"]+")([^>]*>)#', '$1$3', $html); - $html = preg_replace('#<\/?(b|i)>#', '', $html); - - return $html; - } - - public static function getMetaTags($html) - { - $tags = array(); - - $headPos = strpos($html, '</head>'); - if ($headPos === false) { - return $tags; - } - - $head = substr($html, 0, $headPos); - - $offset = 0; - while (true) { - if (preg_match('#<meta[^>]+>#i', $head, $matches, PREG_OFFSET_CAPTURE, $offset)) { - $tag = $matches[0][0]; - $offset = $matches[0][1] + strlen($tag); - $name = null; - $value = null; - - if (preg_match('#(name|property)="(?<name>[^"]+)"#i', $tag, $matches)) { - $name = $matches['name']; - } elseif (preg_match('#itemprop="(?<itemprop>[^"]+)"#i', $tag, $matches)) { - $name = $matches['itemprop']; - } else { - continue; - } - - if (preg_match('#content="(?<value>[^"]+)"#', $tag, $matches)) { - $value = self::entityDecode($matches['value']); - } else { - continue; - } - - $tags[] = array( - 'name' => $name, - 'value' => $value, - ); - } else { - break; - } - } - - return $tags; - } - - public static function getTitleTag($html) - { - if (preg_match('#<title>(?<title>[^<]+)#i', $html, $matches)) { - return self::entityDecode($matches['title']); - } - - return ''; - } - - public static function entityDecode($html) - { - $decoded = $html; - - // required to deal with " etc. - $decoded = html_entity_decode($decoded, ENT_COMPAT, 'UTF-8'); - - // required to deal with Ӓ etc. - $convmap = array(0x0, 0x2FFFF, 0, 0xFFFF); - $decoded = mb_decode_numericentity($decoded, $convmap, 'UTF-8'); - - return $decoded; - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/Http.php b/library/DevHelper/Helper/ShippableHelper/Http.php deleted file mode 100644 index 30f10a8..0000000 --- a/library/DevHelper/Helper/ShippableHelper/Http.php +++ /dev/null @@ -1,110 +0,0 @@ - 3600, - ), $options); - - $cache = null; - $cacheKey = ''; - if ($options['cacheTtl'] > 0) { - $cache = XenForo_Application::getCache(); - } - if ($cache) { - $cacheKey = self::_resolveRedirect_getCacheKey($url); - $resolved = $cache->load($cacheKey, false, true); - if (!empty($resolved)) { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__METHOD__, sprintf('Resolved via cache. ($url=%s, $limit=%d) -> %s', - $url, $limit, $resolved)); - } - - return unserialize($resolved); - } - } - - $resolved = self::_resolveRedirect_curl($url, $limit); - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__METHOD__, sprintf('Resolved via curl. ($url=%s, $limit=%d) -> %s', - $url, $limit, serialize($resolved))); - } - - if (!empty($cache) - && !empty($cacheKey) - ) { - $cache->save(serialize($resolved), $cacheKey, array(), $options['cacheTtl']); - } - - return $resolved; - } - - protected static function _resolveRedirect_curl($url, $limit, array $options = array()) - { - if (!isset($options['originalUrl'])) { - $options['originalUrl'] = $url; - } - if (!isset($options['originalLimit'])) { - $options['originalLimit'] = $limit; - } - - if (!parse_url($url, PHP_URL_HOST)) { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__METHOD__, sprintf('Cannot resolve malformed url. ($url=%s, $limit=%d) -> %s', - $options['originalUrl'], $options['originalLimit'], $url)); - } - - return $url; - } - - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_NOBODY, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - $headers = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - $redirectLocation = ''; - if ($httpCode >= 300 - && $httpCode < 400 - && preg_match('#Location: (?http.+)\s#', $headers, $matches) - ) { - $redirectLocation = $matches['location']; - } - - if ($redirectLocation === '') { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__METHOD__, sprintf('Resolved. ($url=%s, $limit=%d) -> %s', - $options['originalUrl'], $options['originalLimit'], $url)); - } - - return $url; - } - - if ($limit === -1) { - $nextLimit = -1; - } elseif ($limit > 0) { - $nextLimit = $limit - 1; - } else { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__METHOD__, sprintf('Too many redirects! ($url=%s, $limit=%d) -> %s', - $options['originalUrl'], $options['originalLimit'], $url)); - } - - return $url; - } - - return self::_resolveRedirect_curl($redirectLocation, $nextLimit, $options); - } - - protected static function _resolveRedirect_getCacheKey($url) - { - return preg_replace('#[^A-Za-z0-9_]#', '', sprintf('%s_%s', $url, md5(sprintf('%s_%s', $url, __CLASS__)))); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/Image.php b/library/DevHelper/Helper/ShippableHelper/Image.php deleted file mode 100644 index 52eda51..0000000 --- a/library/DevHelper/Helper/ShippableHelper/Image.php +++ /dev/null @@ -1,77 +0,0 @@ - 0 && $height > 0) { - $size = $width; - $mode = $height; - } elseif ($width > 0) { - $size = $width; - $mode = bdImage_Integration::MODE_STRETCH_HEIGHT; - } elseif ($height > 0) { - $size = $height; - $mode = bdImage_Integration::MODE_STRETCH_WIDTH; - } - - return bdImage_Integration::buildThumbnailLink($imageUrl, $size, $mode); - } - - $thumbnailPath = self::getThumbnailPath($imageUrl, $width, $height, $dir); - $thumbnailUrl = XenForo_Link::convertUriToAbsoluteUri(XenForo_Application::$externalDataUrl - . self::_getThumbnailRelativePath($imageUrl, $width, $height, $dir), true); - if (file_exists($thumbnailPath)) { - $thumbnailFileSize = filesize($thumbnailPath); - if ($thumbnailFileSize > 0) { - return sprintf('%s?fs=%d', $thumbnailUrl, $thumbnailFileSize); - } - } - - $coreData = DevHelper_Helper_ShippableHelper_ImageCore::open($imageUrl); - $coreData = DevHelper_Helper_ShippableHelper_ImageCore::thumbnail($coreData, $width, $height); - DevHelper_Helper_ShippableHelper_ImageCore::save($coreData, $thumbnailPath); - - return sprintf('%s?t=%d', $thumbnailUrl, XenForo_Application::$time); - } - - public static function getThumbnailPath($imageUrl, $width, $height = 0, $dir = null) - { - $thumbnailPath = XenForo_Helper_File::getExternalDataPath() - . self::_getThumbnailRelativePath($imageUrl, $width, $height, $dir); - - return $thumbnailPath; - } - - protected static function _getThumbnailRelativePath($imageUrl, $width, $height, $dir) - { - $path = parse_url($imageUrl, PHP_URL_PATH); - $basename = basename($path); - if (empty($basename)) { - $basename = md5($imageUrl); - } - $fileName = preg_replace('#[^a-zA-Z0-9]#', '', $basename) . md5(serialize(array( - 'fullPath' => $imageUrl, - 'width' => $width, - 'height' => $height, - ))); - $ext = XenForo_Helper_File::getFileExtension($basename); - if (!in_array($ext, array('gif', 'jpeg', 'jpg', 'png'), true)) { - $ext = 'jpg'; - } - $divider = substr(md5($fileName), 0, 2); - - if (empty($dir)) { - $dir = trim(str_replace('_', '/', substr(__CLASS__, 0, strpos(__CLASS__, '_ShippableHelper_Image'))), '/'); - } - - return sprintf('/%s/%sx%s/%s/%s.%s', $dir, $width, $height, $divider, $fileName, $ext); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/ImageCore.php b/library/DevHelper/Helper/ShippableHelper/ImageCore.php deleted file mode 100644 index 2372a54..0000000 --- a/library/DevHelper/Helper/ShippableHelper/ImageCore.php +++ /dev/null @@ -1,330 +0,0 @@ -get('maxImageResizePixelCount') - ) { - $image = XenForo_Image_Abstract::createFromFile($accessiblePath, $imageInfo['typeInt']); - } - - return array( - 'image' => $image, - 'imageInfo' => $imageInfo, - ); - } - - /** - * @param array $data - * @param string $path - * @return bool - */ - public static function save(array $data, $path) - { - XenForo_Helper_File::createDirectory(dirname($path), true); - $outputPath = tempnam(XenForo_Helper_File::getTempDir(), __CLASS__); - - /** @noinspection PhpUndefinedMethodInspection */ - $data['image']->output($data['imageInfo']['typeInt'], $outputPath); - return XenForo_Helper_File::safeRename($outputPath, $path); - } - - /** - * @param array $data - * @param int $width - * @param int $height - * @return array() - */ - public static function thumbnail(array $data, $width, $height = 0) - { - $image = $data['image']; - $imageInfo = $data['imageInfo']; - - if (empty($image)) { - // no image input, create a new one - $size = min(100, max($width, $height)); - $image = XenForo_Image_Abstract::createImage($size, $size); - $imageInfo['typeInt'] = IMAGETYPE_PNG; - } - - $isGd = $image instanceof XenForo_Image_Gd; - $isImageMagick = $image instanceof XenForo_Image_ImageMagick_Pecl; - if ($imageInfo['typeInt'] === IMAGETYPE_GIF && $isImageMagick) { - /** @noinspection PhpParamsInspection */ - _DevHelper_Helper_ShippableHelper_ImageCore_ImageMagick::dropFrames($image); - } - - if (in_array($width, array('', 0), true) && $height > 0) { - self::_resizeStretchWidth($image, $height); - } elseif (in_array($height, array('', 0), true) && $width > 0) { - self::_resizeStretchHeight($image, $width); - } elseif ($width > 0 && $height > 0) { - self::_cropExact($image, $width, $height); - } elseif ($width > 0) { - self::_cropSquare($image, $width); - } - - if ($imageInfo['typeInt'] === IMAGETYPE_JPEG) { - if ($isGd) { - /** @noinspection PhpParamsInspection */ - _DevHelper_Helper_ShippableHelper_ImageCore_Gd::progressiveJpeg($image); - } elseif ($isImageMagick) { - /** @noinspection PhpParamsInspection */ - _DevHelper_Helper_ShippableHelper_ImageCore_ImageMagick::progressiveJpeg($image); - } - } - - return array( - 'image' => $image, - 'imageInfo' => $imageInfo, - ); - } - - /** - * @param XenForo_Image_Abstract $imageObj - * @param int $targetHeight - */ - protected static function _resizeStretchWidth(XenForo_Image_Abstract $imageObj, $targetHeight) - { - $targetWidth = $targetHeight / $imageObj->getHeight() * $imageObj->getWidth(); - $imageObj->thumbnail($targetWidth, $targetHeight); - } - - /** - * @param XenForo_Image_Abstract $imageObj - * @param int $targetWidth - */ - protected static function _resizeStretchHeight(XenForo_Image_Abstract $imageObj, $targetWidth) - { - $targetHeight = $targetWidth / $imageObj->getWidth() * $imageObj->getHeight(); - $imageObj->thumbnail($targetWidth, $targetHeight); - } - - /** - * @param XenForo_Image_Abstract $imageObj - * @param int $targetWidth - * @param int $targetHeight - */ - protected static function _cropExact(XenForo_Image_Abstract $imageObj, $targetWidth, $targetHeight) - { - $origRatio = $imageObj->getWidth() / $imageObj->getHeight(); - $cropRatio = $targetWidth / $targetHeight; - if ($origRatio > $cropRatio) { - $thumbnailHeight = $targetHeight; - $thumbnailWidth = $thumbnailHeight * $origRatio; - } else { - $thumbnailWidth = $targetWidth; - $thumbnailHeight = $thumbnailWidth / $origRatio; - } - - if ($thumbnailWidth <= $imageObj->getWidth() - && $thumbnailHeight <= $imageObj->getHeight() - ) { - $imageObj->thumbnail($thumbnailWidth, $thumbnailHeight); - self::_cropCenter($imageObj, $targetWidth, $targetHeight); - } else { - if ($origRatio > $cropRatio) { - self::_cropCenter($imageObj, $imageObj->getHeight() * $cropRatio, $imageObj->getHeight()); - } else { - self::_cropCenter($imageObj, $imageObj->getWidth(), $imageObj->getWidth() / $cropRatio); - } - } - } - - /** - * @param XenForo_Image_Abstract $imageObj - * @param int $target - */ - protected static function _cropSquare(XenForo_Image_Abstract $imageObj, $target) - { - $imageObj->thumbnailFixedShorterSide($target); - self::_cropCenter($imageObj, $target, $target); - } - - /** - * @param XenForo_Image_Abstract $imageObj - * @param int $cropWidth - * @param int $cropHeight - */ - protected static function _cropCenter(XenForo_Image_Abstract $imageObj, $cropWidth, $cropHeight) - { - if (self::$cropTopLeft) { - // revert to top left cropping (old version behavior) - /** @noinspection PhpParamsInspection */ - $imageObj->crop(0, 0, $cropWidth, $cropHeight); - return; - } - - $width = $imageObj->getWidth(); - $height = $imageObj->getHeight(); - $x = floor(($width - $cropWidth) / 2); - $y = floor(($height - $cropHeight) / 2); - - /** @noinspection PhpParamsInspection */ - $imageObj->crop($x, $y, $cropWidth, $cropHeight); - } - - protected static function _getAccessiblePath($path) - { - if (!parse_url($path, PHP_URL_HOST)) { - return $path; - } - - $boardUrl = XenForo_Application::getOptions()->get('boardUrl'); - if (strpos($path, '..') === false - && strpos($path, $boardUrl) === 0 - ) { - $localFilePath = self::_getLocalFilePath(substr($path, strlen($boardUrl))); - if (self::_imageExists($localFilePath)) { - return $localFilePath; - } - } - - if (preg_match('#attachments/(.+\.)*(?\d+)/#', $path, $matches)) { - $fullIndex = XenForo_Link::buildPublicLink('full:index'); - $canonicalIndex = XenForo_Link::buildPublicLink('canonical:index'); - if (strpos($path, $fullIndex) === 0 || strpos($path, $canonicalIndex) === 0) { - $attachmentDataFilePath = self::_getAttachmentDataFilePath($matches['id']); - if (self::_imageExists($attachmentDataFilePath)) { - return $attachmentDataFilePath; - } - } - } - - return DevHelper_Helper_ShippableHelper_TempFile::download($path); - } - - protected static function _getLocalFilePath($path) - { - // remove query parameters - $path = preg_replace('#(\?|\#).*$#', '', $path); - if (strlen($path) === 0) { - return $path; - } - - $extension = XenForo_Helper_File::getFileExtension($path); - if (!in_array($extension, array('gif', 'jpeg', 'jpg', 'png'), true)) { - return ''; - } - - /** @var XenForo_Application $app */ - $app = XenForo_Application::getInstance(); - $path = sprintf('%s/%s', rtrim($app->getRootDir(), '/'), ltrim($path, '/')); - - return $path; - } - - protected static function _getAttachmentDataFilePath($attachmentId) - { - /** @var XenForo_Model_Attachment $attachmentModel */ - static $attachmentModel = null; - static $attachments = array(); - - if ($attachmentModel === null) { - $attachmentModel = XenForo_Model::create('XenForo_Model_Attachment'); - } - - if (!isset($attachments[$attachmentId])) { - $attachments[$attachmentId] = $attachmentModel->getAttachmentById($attachmentId); - } - - if (empty($attachments[$attachmentId])) { - return ''; - } - - return $attachmentModel->getAttachmentDataFilePath($attachments[$attachmentId]); - } - - protected static function _imageExists($path) - { - if (!is_string($path) || strlen($path) === 0) { - // invalid path - return false; - } - - $pathSize = @filesize($path); - if (!is_int($pathSize)) { - // file not exists - return false; - } - - // according to many sources, no valid image can be smaller than 14 bytes - // http://garethrees.org/2007/11/14/pngcrush/ - // https://github.com/mathiasbynens/small/blob/master/gif.gif - return $pathSize >= 14; - } - - protected static function _getImageInfo($path) - { - $imageInfo = array(); - - $fileSize = @filesize($path); - if (!empty($fileSize)) { - $imageInfo['fileSize'] = $fileSize; - } - - if (!empty($imageInfo['fileSize']) - && $info = @getimagesize($path) - ) { - $imageInfo['width'] = $info[0]; - $imageInfo['height'] = $info[1]; - $imageInfo['typeInt'] = $info[2]; - } - - return $imageInfo; - } -} - -class _DevHelper_Helper_ShippableHelper_ImageCore_Gd extends XenForo_Image_Gd -{ - public static function progressiveJpeg(XenForo_Image_Gd $obj) - { - imageinterlace($obj->_image, 1); - } -} - -class _DevHelper_Helper_ShippableHelper_ImageCore_ImageMagick extends XenForo_Image_ImageMagick_Pecl -{ - public static function dropFrames(XenForo_Image_ImageMagick_Pecl $obj) - { - $image = $obj->_image; - - if ($image->count() > 1) { - $newImage = null; - - foreach ($image as $frame) { - $newImage = new Imagick(); - $newImage->addImage($frame->getImage()); - break; - } - - if ($newImage !== null) { - $obj->_image = $newImage; - $image->destroy(); - } - } - } - - public static function progressiveJpeg(XenForo_Image_ImageMagick_Pecl $obj) - { - $obj->_image->setInterlaceScheme(Imagick::INTERLACE_PLANE); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/ImageSize.php b/library/DevHelper/Helper/ShippableHelper/ImageSize.php deleted file mode 100644 index 2067660..0000000 --- a/library/DevHelper/Helper/ShippableHelper/ImageSize.php +++ /dev/null @@ -1,542 +0,0 @@ - 2000 - || strpos($uri, ' ') !== false - || strpos($uri, 'data:') === 0 - ) { - return array( - 'uri' => $uri, - 'width' => 0, - 'height' => 0, - 'timestamp' => time(), - ); - } - - $cacheId = __CLASS__ . md5($uri); - $cache = ($ttl > 0 ? XenForo_Application::getCache() : null); - - if ($cache) { - $cachedData = $cache->load($cacheId); - if (is_string($cachedData)) { - $cachedData = unserialize($cachedData); - } - if (!is_array($cachedData)) { - $cachedData = array(); - } - if (!empty($cachedData['uri']) - && $cachedData['uri'] === $uri - && XenForo_Application::$time - $cachedData['timestamp'] < $ttl - ) { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('$uri=%s; CACHE HIT', $uri)); - } - return $cachedData; - } - } - - $originalUri = $uri; - $requestPaths = XenForo_Application::get('requestPaths'); - if (strpos($uri, $requestPaths['fullBasePath']) === 0) { - $uri = substr($uri, strlen($requestPaths['fullBasePath'])); - } - - $data = self::_calculate($uri); - if (empty($data['width']) - || empty($data['height']) - ) { - $absoluteUri = XenForo_Link::convertUriToAbsoluteUri($uri, true); - if ($absoluteUri != $uri) { - $data = self::_calculate($absoluteUri); - } - } - - if (!empty($data['uri']) - && $data['uri'] != $originalUri - ) { - $data['_calculateUri'] = $data['uri']; - } - $data['uri'] = $originalUri; - - if ($cache) { - $cache->save(serialize($data), $cacheId, array(), $ttl); - } - - return $data; - } - - public static function getDataUriMatchesRatio($uri, $rgba = null) - { - if (!function_exists('imagecreatetruecolor')) { - return ''; - } - - $calculated = self::calculate($uri); - if ($calculated['width'] < 1 || $calculated['height'] < 1) { - return ''; - } - - return self::getDataUriAtSize($calculated['width'], $calculated['height'], $rgba); - } - - public static function getDataUriAtSize($width, $height, $rgba = null) - { - if (!function_exists('imagecreatetruecolor') || $width < 1 || $height < 1) { - return ''; - } - - $gcd = self::_findGreatestCommonDivisor($width, $height); - $width /= $gcd; - $height /= $gcd; - - $image = imagecreate($width, $height); - imagealphablending($image, false); - imagesavealpha($image, true); - if (!is_array($rgba) || count($rgba) < 3) { - $color = imagecolorallocatealpha($image, 255, 255, 255, 127); - } else { - $rgba = array_values($rgba); - $r = max(0, min(255, $rgba[0] < 1 ? floor(255 * $rgba[0]) : $rgba[0])); - $g = max(0, min(255, $rgba[1] < 1 ? floor(255 * $rgba[1]) : $rgba[0])); - $b = max(0, min(255, $rgba[2] < 1 ? floor(255 * $rgba[2]) : $rgba[0])); - $a = isset($rgba[3]) ? max(0, min(127, $rgba[3] < 1 ? floor(127 * $rgba[3]) : $rgba[0])) : 0; - $color = imagecolorallocatealpha($image, $r, $g, $b, $a); - } - imagefilledrectangle($image, 0, 0, $width, $height, $color); - - ob_start(); - imagepng($image); - $imageBytes = ob_get_contents(); - ob_end_clean(); - - return 'data:image/png;base64,' . base64_encode($imageBytes); - } - - protected static function _calculate($uri) - { - /** @var self $instance */ - static $instance = null; - - $startTime = microtime(true); - - if (preg_match('#^(?.+)?attachments/(.+\.)*(?\d+)/#', $uri, $matches) - && ($matches['prefix'] === '' - || strpos($matches['prefix'], XenForo_Link::buildPublicLink('full:index')) === 0 - || strpos($matches['prefix'], XenForo_Link::buildPublicLink('canonical:index')) === 0 - ) - ) { - $attachmentResult = self::_calculateForAttachment($uri, $matches['id']); - if (!empty($attachmentResult['width']) - && !empty($attachmentResult['height']) - ) { - return $attachmentResult; - } - } - - if ($instance === null) { - $instance = new self($uri); - } else { - $instance->close(); - $instance->load($uri); - } - - list($width, $height) = $instance->getSize(); - - if (XenForo_Application::debugMode()) { - $elapsedTime = microtime(true) - $startTime; - XenForo_Helper_File::log(__CLASS__, sprintf('$uri=%s; $width=%d, $height=%d; $elapsedTime=%.6f', - $uri, $width, $height, $elapsedTime)); - } - - return array( - 'uri' => $uri, - 'width' => $width, - 'height' => $height, - 'timestamp' => time(), - ); - } - - protected static function _calculateForAttachment($uri, $attachmentId) - { - $startTime = microtime(true); - - /** @var XenForo_Model_Attachment $attachmentModel */ - static $attachmentModel = null; - static $attachments = array(); - - if ($attachmentModel === null) { - $attachmentModel = XenForo_Model::create('XenForo_Model_Attachment'); - } - - if (!isset($attachments[$attachmentId])) { - $attachments[$attachmentId] = $attachmentModel->getAttachmentById($attachmentId); - } - - $width = 0; - if (!empty($attachments[$attachmentId]['width'])) { - $width = intval($attachments[$attachmentId]['width']); - } - - $height = 0; - if (!empty($attachments[$attachmentId]['height'])) { - $height = intval($attachments[$attachmentId]['height']); - } - - if (XenForo_Application::debugMode()) { - $elapsedTime = microtime(true) - $startTime; - XenForo_Helper_File::log(__CLASS__, sprintf('$uri=%s; $attachmentId=%d, $width=%d, $height=%d;' - . ' $elapsedTime=%.6f', $uri, $attachmentId, $width, $height, $elapsedTime)); - } - - return array( - 'uri' => $uri, - 'attachmentId' => $attachmentId, - 'width' => $width, - 'height' => $height, - 'timestamp' => time(), - ); - } - - protected static function _findGreatestCommonDivisor($a, $b) - { - $mod = $a % $b; - if ($mod === 0) { - return $b; - } else { - return self::_findGreatestCommonDivisor($b, $mod); - } - } - - // https://github.com/tommoor/fastimage/commit/7bf53fcfebb5bc04b78a8cf23862778256de2241 - private $pos = 0; - private $str; - private $type; - private $handle; - - private function __construct($uri = null) - { - if ($uri) { - $this->load($uri); - } - } - - private function load($uri) - { - if ($this->handle) { - $this->close(); - } - - $context = null; - $host = parse_url($uri, PHP_URL_HOST); - if ($host) { - $httpContext = array('timeout' => 2.0); - $httpContext['header'] = "Referer: http://$host\r\n"; - - if (!empty($_SERVER['HTTP_USER_AGENT'])) { - $httpContext['user_agent'] = $_SERVER['HTTP_USER_AGENT']; - } else { - $httpContext['user_agent'] = 'Mozilla/4.0 (MSIE 6.0; Windows NT 5.0)'; - } - - $context = stream_context_create(array( - 'http' => $httpContext, - 'ssl' => array( - 'verify_peer' => false, - 'verify_peer_name' => false, - 'allow_self_signed' => true, - ) - )); - } - - if ($context != null) { - $this->handle = @fopen($uri, 'rb', null, $context); - } else { - $this->handle = @fopen($uri, 'rb'); - } - } - - private function close() - { - if ($this->handle) { - if (is_resource($this->handle)) { - fclose($this->handle); - } - - $this->handle = null; - $this->type = null; - $this->str = null; - } - } - - private function getSize() - { - $this->pos = 0; - if (!$this->getType()) { - return array(0, 0); - } - - $size = $this->parseSize(); - if (!is_array($size) || count($size) < 2) { - return array(0, 0); - } - - return array_map('intval', array_values($size)); - } - - private function getType() - { - $this->pos = 0; - - if (!$this->type) { - switch ($this->getChars(2)) { - case 'BM': - return $this->type = 'bmp'; - case 'GI': - return $this->type = 'gif'; - case chr(0xFF) . chr(0xd8): - return $this->type = 'jpeg'; - case chr(0x89) . 'P': - return $this->type = 'png'; - case 'II': - case 'MM': - return $this->type = 'tiff'; - case 'RI': - return $this->type = 'webp'; - default: - return false; - } - } - - return $this->type; - } - - private function parseSize() - { - $this->pos = 0; - - $method = 'parseSizeFor' . strtoupper($this->type); - if (is_callable(array($this, $method))) { - return call_user_func(array($this, $method)); - } - - return null; - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForPNG() - { - $chars = $this->getChars(25); - - return unpack('N*', substr($chars, 16, 8)); - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForGIF() - { - $chars = $this->getChars(11); - - return unpack('S*', substr($chars, 6, 4)); - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForBMP() - { - $chars = $this->getChars(29); - $chars = substr($chars, 14, 14); - $type = unpack('C', $chars); - - return (reset($type) == 40) ? unpack('L*', substr($chars, 4)) : unpack('L*', substr($chars, 4, 8)); - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForJPEG() - { - $state = null; - $skip = 0; - - while (true) { - switch ($state) { - default: - $this->getChars(2); - $state = 'started'; - break; - - case 'started': - $b = $this->getByte(); - if ($b === false) { - return false; - } - - $state = $b == 0xFF ? 'sof' : 'started'; - break; - - case 'sof': - $b = $this->getByte(); - if (in_array($b, range(0xe0, 0xef), true)) { - $state = 'skipframe'; - } elseif (in_array($b, array_merge(range(0xC0, 0xC3), range(0xC5, 0xC7), - range(0xC9, 0xCB), range(0xCD, 0xCF)), true)) { - $state = 'readsize'; - } elseif ($b === 0xFF) { - $state = 'sof'; - } else { - $state = 'skipframe'; - } - break; - - case 'skipframe': - $skip = $this->readInt($this->getChars(2)) - 2; - $state = 'doskip'; - break; - - case 'doskip': - $this->getChars($skip); - $state = 'started'; - break; - - case 'readsize': - $c = $this->getChars(7); - - return array($this->readInt(substr($c, 5, 2)), $this->readInt(substr($c, 3, 2))); - } - } - - return array(0, 0); - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForWEBP() - { - $chars = $this->getChars(30); - $result = unpack('C12/S9', $chars); - - return array($result['8'], $result['9']); - } - - /** @noinspection PhpUnusedPrivateMethodInspection */ - private function parseSizeForTIFF() - { - $byteOrder = $this->getChars(2); - switch ($byteOrder) { - case 'II': - $short = 'v'; - $long = 'V'; - break; - case 'MM': - $short = 'n'; - $long = 'N'; - break; - default: - return false; - break; - } - - $this->getChars(2); - $offset = current(unpack($long, $this->getChars(4))); - - $this->getChars($offset - 8); - $tagCount = current(unpack($short, $this->getChars(2))); - - for ($i = $tagCount; $i > 0; $i--) { - $type = current(unpack($short, $this->getChars(2))); - $this->getChars(6); - $data = current(unpack($short, $this->getChars(2))); - switch ($type) { - case 0x0100: - $width = $data; - break; - case 0x0101: - $height = $data; - break; - case 0x0112: - $orientation = $data; - break; - } - if (isset($width) && isset($height) && isset($orientation)) { - if ($orientation >= 5) { - return array($height, $width); - } - return array($width, $height); - } - $this->getChars(2); - } - - return array(0, 0); - } - - private function getChars($n) - { - if (!is_resource($this->handle)) { - return false; - } - - $response = null; - - // do we need more data? - if ($this->pos + $n - 1 >= strlen($this->str)) { - $end = ($this->pos + $n); - - while (strlen($this->str) < $end && $response !== false) { - // read more from the file handle - $need = $end - ftell($this->handle); - - if ($response = fread($this->handle, $need)) { - $this->str .= $response; - } else { - return false; - } - } - } - - $result = substr($this->str, $this->pos, $n); - $this->pos += $n; - - if (function_exists('mb_convert_encoding')) { - $result = mb_convert_encoding($result, '8BIT', '7BIT'); - } - - return $result; - } - - private function getByte() - { - $c = $this->getChars(1); - if (!is_string($c) || strlen($c) === 0) { - return false; - } - - $b = unpack('C', $c); - - return reset($b); - } - - private function readInt($str) - { - $size = unpack('C*', $str); - if (!isset($size[1]) || !isset($size[2])) { - return 0; - } - - return ($size[1] << 8) + $size[2]; - } - - public function __destruct() - { - $this->close(); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/S3.php b/library/DevHelper/Helper/ShippableHelper/S3.php deleted file mode 100644 index 858f077..0000000 --- a/library/DevHelper/Helper/ShippableHelper/S3.php +++ /dev/null @@ -1,227 +0,0 @@ -_region = $region; - - switch ($region) { - case 'us-east-1': - // default endpoint is correct for this region - break; - default: - $this->setEndpoint(sprintf('http://s3-%s.amazonaws.com', $region)); - } - } - - public function setSignatureAws4($enabled) - { - $this->_signatureAws4 = $enabled; - } - - public function _makeRequest($method, $path = '', $params = null, $headers = array(), $data = null) - { - if (empty($params)) { - $params = array(); - } - - if (!is_array($headers)) { - $headers = array($headers); - } - - if (is_resource($data)) { - throw new Zend_Service_Amazon_S3_Exception("No support for stream data"); - } - $data = strval($data); - - // build the end point (with path) - $endpoint = clone($this->_endpoint); - $endpoint->setPath('/' . $path); - - $retryCount = 0; - - if ($this->_signatureAws4) { - if (isset($headers['Content-MD5'])) { - unset($headers['Content-MD5']); - } - - $headers['x-amz-content-sha256'] = Zend_Crypt::hash('sha256', $data); - $headers['x-amz-date'] = sprintf( - '%sT%sZ', - gmdate('Ymd', XenForo_Application::$time), - gmdate('His', XenForo_Application::$time) - ); - $headers['Host'] = parse_url($endpoint, PHP_URL_HOST); - - $this->addSignatureAws4($method, $path, $params, $headers); - } else { - $headers['Date'] = gmdate(DATE_RFC1123, time()); - self::addSignature($method, $path, $headers); - } - - $client = self::getHttpClient(); - - $client->resetParameters(); - $client->setUri($endpoint); - $client->setAuth(false); - $client->setHeaders($headers); - - if (is_array($params)) { - foreach ($params as $name => $value) { - $client->setParameterGet($name, $value); - } - } - - if (($method == 'PUT') && ($data !== null)) { - if (!isset($headers['Content-type'])) { - $headers['Content-type'] = self::getMimeType($path); - } - $client->setRawData($data, $headers['Content-type']); - } - - do { - $retry = false; - - $response = $client->request($method); - $responseCode = $response->getStatus(); - - if (XenForo_Application::debugMode() || $responseCode != 200) { - XenForo_Helper_File::log(__METHOD__, sprintf( - "%s %s %s -> %d %s\n\n", - $method, - $endpoint->getUri(), - var_export($headers, true), - $responseCode, - $responseCode != 200 - ? $response->getBody() - : sprintf('Body(length=%d)', strlen($response->getBody())) - )); - } - - // some 5xx errors are expected, so retry automatically - if ($responseCode >= 500 && $responseCode < 600 && $retryCount <= 5) { - $retry = true; - $retryCount++; - sleep($retryCount / 4 * $retryCount); - } elseif ($responseCode == 307) { - // need to redirect, new S3 endpoint given - // this should never happen as Zend_Http_Client will redirect automatically - } elseif ($responseCode == 100) { - // 'OK to Continue'; - } - } while ($retry); - - return $response; - } - - protected function addSignatureAws4($method, $path, array $params, array &$headers) - { - // http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html - // task 1: create a canonical request - $canonicalQueryArray = array(); - if (!empty($params)) { - ksort($params); - foreach ($params as $paramKey => $paramValue) { - $canonicalQueryArray[] = sprintf('%s=%s', urlencode($paramKey), urlencode($paramValue)); - } - } - $canonicalQueryString = implode('&', $canonicalQueryArray); - - $canonicalHeaders = ''; - $signedHeadersArray = array(); - $hashedPayload = ''; - $timestamp = ''; - $headerKeys = array_combine(array_map('strtolower', array_keys($headers)), array_keys($headers)); - ksort($headerKeys); - foreach ($headerKeys as $headerKeyLower => $headerKey) { - $canonicalHeaders .= sprintf("%s:%s\n", $headerKeyLower, $headers[$headerKey]); - $signedHeadersArray[] = $headerKeyLower; - - switch ($headerKey) { - case 'x-amz-content-sha256': - $hashedPayload = $headers[$headerKey]; - break; - case 'x-amz-date': - $timestamp = $headers[$headerKey]; - break; - } - } - $signedHeadersString = implode(';', $signedHeadersArray); - - $canonicalRequest = sprintf( - "%s\n/%s\n%s\n%s\n%s\n%s", - $method, - $path, - $canonicalQueryString, - $canonicalHeaders, - $signedHeadersString, - $hashedPayload - ); - - // task 2: create a string to sign - $date = substr($timestamp, 0, strpos($timestamp, 'T')); - $scope = sprintf( - '%s/%s/s3/aws4_request', - $date, - $this->_region - ); - $stringToSign = sprintf( - "AWS4-HMAC-SHA256\n%s\n%s\n%s", - $timestamp, - $scope, - Zend_Crypt::hash('sha256', $canonicalRequest) - ); - - // task 3: calculate signature - $dateKey = Zend_Crypt_Hmac::compute('AWS4' . $this->_getSecretKey(), 'sha256', - $date, Zend_Crypt_Hmac::BINARY); - $dateRegionKey = Zend_Crypt_Hmac::compute($dateKey, - 'sha256', $this->_region, Zend_Crypt_Hmac::BINARY); - $dateRegionServiceKey = Zend_Crypt_Hmac::compute($dateRegionKey, - 'sha256', 's3', Zend_Crypt_Hmac::BINARY); - $signingKey = Zend_Crypt_Hmac::compute($dateRegionServiceKey, - 'sha256', 'aws4_request', Zend_Crypt_Hmac::BINARY); - - $signature = Zend_Crypt_Hmac::compute($signingKey, 'sha256', $stringToSign); - $headers['Authorization'] = sprintf( - 'AWS4-HMAC-SHA256 Credential=%s/%s,SignedHeaders=%s,Signature=%s', - $this->_getAccessKey(), - $scope, - $signedHeadersString, - $signature - ); - - return $signature; - } - - public static function getRegions() - { - // http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region - return array( - 'us-east-1' => 'US East (N. Virginia)', - 'us-east-2' => 'US East (Ohio)', - 'us-west-1' => 'US West (N. California)', - 'us-west-2' => 'US West (Oregon)', - 'ca-central-1' => 'Canada (Central)', - 'ap-south-1' => 'Asia Pacific (Mumbai)', - 'ap-northeast-2' => 'Asia Pacific (Seoul)', - 'ap-southeast-1' => 'Asia Pacific (Singapore)', - 'ap-southeast-2' => 'Asia Pacific (Sydney)', - 'ap-northeast-1' => 'Asia Pacific (Tokyo)', - 'eu-central-1' => 'EU (Frankfurt)', - 'eu-west-1' => 'EU (Ireland)', - 'eu-west-2' => 'EU (London)', - 'sa-east-1' => 'South America (São Paulo)', - ); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/String.php b/library/DevHelper/Helper/ShippableHelper/String.php deleted file mode 100644 index 730a7c2..0000000 --- a/library/DevHelper/Helper/ShippableHelper/String.php +++ /dev/null @@ -1,26 +0,0 @@ - 1024 && $unitKey < count($units) - 1) { - $bytes /= 1024; - $unitKey++; - } - - // get float with one decimal place - // truncate if it's insignificant though - $value = sprintf('%.1f', $bytes); - $value = preg_replace('#\.0$#', '', $value); - - return sprintf('%s %s', $value, $units[$unitKey]); - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/TempFile.php b/library/DevHelper/Helper/ShippableHelper/TempFile.php deleted file mode 100644 index e82e72b..0000000 --- a/library/DevHelper/Helper/ShippableHelper/TempFile.php +++ /dev/null @@ -1,213 +0,0 @@ - '', - 'userAgent' => '', - 'timeOutInSeconds' => 0, - 'maxRedirect' => 3, - 'maxDownloadSize' => XenForo_Application::getOptions()->get('attachmentMaxFileSize') * 1024, - 'secured' => 0, - ); - - $tempFile = trim(strval($options['tempFile'])); - $managedTempFile = false; - if (strlen($tempFile) === 0) { - $tempFile = tempnam(XenForo_Helper_File::getTempDir(), self::_getPrefix()); - $managedTempFile = true; - } - if (strlen($tempFile) === 0) { - return false; - } - - if (isset(self::$_cached[$url]) - && filesize(self::$_cached[$url]) > 0 - ) { - if ($managedTempFile) { - unlink($tempFile); - return self::$_cached[$url]; - } else { - copy(self::$_cached[$url], $tempFile); - return $tempFile; - } - } - - if ($managedTempFile) { - self::cache($url, $tempFile); - } - - self::$_maxDownloadSize = $options['maxDownloadSize']; - - $fh = fopen($tempFile, 'wb'); - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_FILE, $fh); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_NOPROGRESS, 0); - curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array(__CLASS__, 'download_curlProgressFunction')); - - if (!empty($options['userAgent'])) { - curl_setopt($ch, CURLOPT_USERAGENT, $options['userAgent']); - } - if ($options['timeOutInSeconds'] > 0) { - curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeOutInSeconds']); - } - if ($options['maxRedirect'] > 0) { - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($ch, CURLOPT_MAXREDIRS, $options['maxRedirect']); - } else { - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); - } - if ($options['secured'] === 0) { - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - } - - curl_exec($ch); - $curlInfo = curl_getinfo($ch); - curl_close($ch); - fclose($fh); - - $downloaded = true; - if (!isset($curlInfo['http_code']) - || $curlInfo['http_code'] < 200 - || $curlInfo['http_code'] >= 300 - ) { - // no http response status / non success status, must be an error - $downloaded = false; - } - - $fileSize = filesize($tempFile); - if ($downloaded && $fileSize === 0) { - clearstatcache(); - $fileSize = filesize($tempFile); - } - - if ($downloaded - && isset($curlInfo['size_download']) - && $fileSize !== intval($curlInfo['size_download']) - ) { - // file size reported by our system seems to be off, probably a write error - $downloaded = false; - } - - if ($downloaded - && isset($curlInfo['download_content_length']) - && $curlInfo['download_content_length'] > 0 - && $fileSize !== intval($curlInfo['download_content_length']) - ) { - // file size is different from Content-Length header, probably a cancelled download (or corrupted) - $downloaded = false; - } - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, call_user_func_array('sprintf', array( - 'download %s -> %s, %s, %s', - $url, - $tempFile, - ($downloaded ? 'succeeded' : 'failed'), - json_encode($curlInfo), - ))); - } - - if ($downloaded) { - return $tempFile; - } else { - file_put_contents($tempFile, ''); - return false; - } - } - - public static function download_curlProgressFunction($downloadSize, $downloaded) - { - return ((self::$_maxDownloadSize > 0 - && ($downloadSize > self::$_maxDownloadSize - || $downloaded > self::$_maxDownloadSize)) - ? 1 : 0); - } - - public static function deleteAllCached() - { - foreach (self::$_cached as $url => $tempFile) { - if (XenForo_Application::debugMode()) { - $fileSize = @filesize($tempFile); - } - - $deleted = @unlink($tempFile); - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, call_user_func_array('sprintf', array( - 'delete %s -> %s, %s, %d bytes', - $url, - $tempFile, - ($deleted ? 'succeeded' : 'failed'), - (!empty($fileSize) ? $fileSize : 0), - ))); - } - } - - self::$_cached = array(); - } - - protected static function _getPrefix() - { - static $prefix = null; - - if ($prefix === null) { - $prefix = strtolower(preg_replace('#[^A-Z]#', '', __CLASS__)) . '_'; - } - - return $prefix; - } - -} diff --git a/library/DevHelper/Helper/ShippableHelper/Updater.php b/library/DevHelper/Helper/ShippableHelper/Updater.php deleted file mode 100644 index 6a0e0c4..0000000 --- a/library/DevHelper/Helper/ShippableHelper/Updater.php +++ /dev/null @@ -1,195 +0,0 @@ - array(), - 'onPreRoute' => array(), - 'setupMethod' => array(), - 'addOns' => array(), - ); - } - - $GLOBALS[self::KEY]['version'][$apiUrl][self::$_version] - = 'DevHelper_Helper_ShippableHelper_UpdaterCore'; - - if (!isset($GLOBALS[self::KEY]['onPreRoute'][$apiUrl])) { - $GLOBALS[self::KEY]['onPreRoute'][$apiUrl] = create_function('$fc', - __CLASS__ . '::onPreRoute($fc, ' . var_export($config, true) . ');'); - XenForo_CodeEvent::addListener('front_controller_pre_route', - $GLOBALS[self::KEY]['onPreRoute'][$apiUrl]); - } - - $GLOBALS[self::KEY][$apiUrl]['addOns'][$addOnId] = true; - } - - /** - * Removes trace of Updater if it is no longer needed. - * - * @param string|null $apiUrl - * @param string|null $addOnId - * @throws Zend_Exception - */ - public static function onUninstall($apiUrl = null, $addOnId = null) - { - if (XenForo_Application::$versionId < 1020000) { - // only run if XenForo is at least 1.2.0 - return; - } - - if (!is_string($apiUrl)) { - // use default api url if nothing provided - $apiUrl = self::API_URL; - } - - $addOnId = self::_getAddOnId($addOnId); - $config = self::_readConfig($addOnId, $apiUrl); - $addOns = XenForo_Application::get('addOns'); - - $activeAddOnIds = array(); - foreach ($config['addOnIds'] as $configAddOnId) { - if ($configAddOnId === $addOnId - || !isset($addOns[$configAddOnId]) - ) { - continue; - } - - $activeAddOnIds[] = $configAddOnId; - } - - if (empty($activeAddOnIds)) { - // no active add-ons found, trigger uninstall routine - DevHelper_Helper_ShippableHelper_UpdaterCore::_uninstallSelf($apiUrl); - } - } - - /** - * Finds the latest Updater version and let it setup. - * THIS METHOD SHOULD NOT BE ALTERED BETWEEN VERSIONS. - * - * @param XenForo_FrontController $fc - * @param array $config - * - * @internal - */ - public static function onPreRoute( - /** @noinspection PhpUnusedParameterInspection */ - XenForo_FrontController $fc, - array $config - ) { - if (empty($GLOBALS[self::KEY]['version'][$config['apiUrl']])) { - return; - } - $versions = $GLOBALS[self::KEY]['version'][$config['apiUrl']]; - - ksort($versions); - $latest = array_pop($versions); - - call_user_func(array($latest, 'bootstrap'), $config); - } - - public static function getConfigOptionId($apiUrl) - { - $configOptionId = sprintf('updater%s%s', str_replace(' ', '', ucwords(preg_replace('#[^A-Za-z]+#', ' ', - parse_url($apiUrl, PHP_URL_HOST)))), md5($apiUrl)); - if (strlen($configOptionId) > 50) { - $configOptionId = 'updater_' . md5($configOptionId); - } - - return $configOptionId; - } - - private static function _getAddOnId($addOnId) - { - if ($addOnId !== null) { - return $addOnId; - } - - $clazz = __CLASS__; - $strPos = strpos($clazz, '_ShippableHelper_'); - if ($strPos === false) { - throw new XenForo_Exception('Unable to determine $addOnId'); - } - - return substr($clazz, 0, $strPos); - } - - private static function _readConfig($addOnId, $apiUrl) - { - $options = XenForo_Application::getOptions(); - - $configOptionId = self::getConfigOptionId($apiUrl); - $config = $options->get($configOptionId); - - if ($config === null) { - $config = array( - 'version' => 0, - 'apiUrl' => $apiUrl, - 'addOnIds' => array($addOnId), - - 'enabled' => false, - 'ignored' => array(), - ); - } - - return $config; - } -} \ No newline at end of file diff --git a/library/DevHelper/Helper/ShippableHelper/UpdaterCore.php b/library/DevHelper/Helper/ShippableHelper/UpdaterCore.php deleted file mode 100644 index 586771d..0000000 --- a/library/DevHelper/Helper/ShippableHelper/UpdaterCore.php +++ /dev/null @@ -1,794 +0,0 @@ -$config.apiUrlviewName) { - case 'XenForo_ViewAdmin_AddOn_List': - self::_onAddOnList($controllerResponse, $containerParams); - break; - case 'XenForo_ViewAdmin_AddOn_Upgrade': - self::_onAddOnUpgrade($controllerResponse); - break; - } - } - - private static function _onAddOnList(XenForo_ControllerResponse_View &$controllerResponse, array &$containerParams) - { - $message = ''; - - if (!empty($_GET[self::PARAM_ENABLE]) - && $_GET[self::PARAM_ENABLE] === self::$_config['apiUrl'] - ) { - self::$_config['configured'] = true; - self::$_config['enabled'] = true; - self::_saveConfig(self::$_config); - $controllerResponse = new XenForo_ControllerResponse_Redirect(); - $controllerResponse->redirectType = XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED; - $controllerResponse->redirectTarget = XenForo_Link::buildAdminLink('add-ons'); - return; - } - - if (!empty($_GET[self::PARAM_DISABLE]) - && $_GET[self::PARAM_DISABLE] === self::$_config['apiUrl'] - ) { - self::$_config['configured'] = true; - self::$_config['enabled'] = false; - self::_saveConfig(self::$_config); - $controllerResponse = new XenForo_ControllerResponse_Redirect(); - $controllerResponse->redirectType = XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED; - $controllerResponse->redirectTarget = XenForo_Link::buildAdminLink('add-ons'); - return; - } - - if (empty(self::$_config['configured'])) { - if (!self::$_isBeta - || XenForo_Application::debugMode() - ) { - $enabledAddOnIds = self::_getEnabledAddOnIds(self::$_config['addOnIds']); - - if (!empty($enabledAddOnIds)) { - /** @noinspection HtmlUnknownTarget */ - $message .= sprintf('Updater for %s: enable or disable?', - implode(', ', $enabledAddOnIds), - XenForo_Link::buildAdminLink('add-ons', null, array( - self::PARAM_ENABLE => self::$_config['apiUrl'], - )), - XenForo_Link::buildAdminLink('add-ons', null, array( - self::PARAM_DISABLE => self::$_config['apiUrl'], - )) - ); - - if (self::$_isBeta) { - $message .= ' Warning: The Updater is currently in beta.'; - } - } - } - } elseif (self::$_config['configured']) { - $forceRefresh = (!empty($_GET[self::PARAM_FORCE]) && $_GET[self::PARAM_FORCE] === self::$_config['apiUrl']); - $data = self::_refreshData(self::$_config['apiUrl'], self::$_config['addOnIds'], $forceRefresh); - - if (!empty($data)) { - $message .= self::_onAddOnShowStatuses($data, $forceRefresh); - } - - } - - $paramKey = '_' . md5(self::$_config['apiUrl']); - $containerParams[$paramKey] = array('message' => $message); - } - - private static function _onAddOnShowStatuses(array $data, $forceRefresh) - { - $statuses = ''; - $xenAddOns = XenForo_Application::get('addOns'); - - foreach ($xenAddOns as $addOnId => $addOnVersionId) { - if (!in_array($addOnId, self::$_config['addOnIds'], true)) { - continue; - } - - if (!isset($data[$addOnId])) { - if ($forceRefresh) { - $statuses .= sprintf('%1$s cannot be verified with the Updater Server.
', $addOnId); - } - continue; - } - - if ($addOnVersionId < $data[$addOnId]['version_id']) { - $ignoredVersionId = 0; - if (!empty(self::$_config['ignored'][$addOnId])) { - $ignoredVersionId = self::$_config['ignored'][$addOnId]; - } - $isIgnored = $data[$addOnId]['version_id'] <= $ignoredVersionId; - - $actions = array(); - if ($forceRefresh - || !$isIgnored - ) { - if (!empty($data[$addOnId]['links']['permalink'])) { - /** @noinspection HtmlUnknownTarget */ - $actions[] = sprintf('read more', $data[$addOnId]['links']['permalink']); - } - - if (!empty($data[$addOnId]['links']['content'])) { - /** @noinspection HtmlUnknownTarget */ - $actions[] = sprintf('update', - XenForo_Link::buildAdminLink('full:add-ons/upgrade', - array('addon_id' => $addOnId), - array(self::PARAM_DOWNLOAD => self::$_config['apiUrl']))); - } elseif (!empty($data[$addOnId]['links']['authorize'])) { - $authorizeUrl = sprintf('%s&redirect_uri=%s', - $data[$addOnId]['links']['authorize'], - rawurlencode(XenForo_Link::buildAdminLink('full:add-ons/upgrade', - array('addon_id' => $addOnId), - array(self::PARAM_AUTHORIZE => self::$_config['apiUrl']))) - ); - - /** @noinspection HtmlUnknownTarget */ - $actions[] = sprintf('authorize an update', $authorizeUrl); - } - } - - if (!empty($actions)) { - $outOfDateMessage = sprintf('%1$s is out of date, latest version is v%3$s (#%4$d, yours is #%2$d).', - $addOnId, - $addOnVersionId, - $data[$addOnId]['version_string'], - $data[$addOnId]['version_id']); - - $ignoreMessage = ''; - if (!$isIgnored) { - /** @noinspection HtmlUnknownTarget */ - $ignoreMessage = sprintf(' or ignore this version', - XenForo_Link::buildAdminLink('full:add-ons/upgrade', - array('addon_id' => $addOnId), - array(self::PARAM_IGNORE => self::$_config['apiUrl']))); - } - - $statuses .= sprintf('%1$s You may: %2$s%3$s.
', - $outOfDateMessage, - implode(', ', $actions), - $ignoreMessage); - } - } else { - if ($forceRefresh) { - if ($addOnVersionId > $data[$addOnId]['version_id']) { - $statuses .= sprintf('%1$s appears to be even newer than' - . ' reported from the Updater Server: their v%3$s (#%4$d) vs. your #%2$d.' - . ' Awesome!
', - $addOnId, - $addOnVersionId, - $data[$addOnId]['version_string'], - $data[$addOnId]['version_id']); - } else { - $statuses .= sprintf('%1$s is up to date.
', $addOnId); - } - } - } - } - - return $statuses; - } - - private static function _onAddOnUpgrade(XenForo_ControllerResponse_View &$controllerResponse) - { - if (!empty($_GET[self::PARAM_AUTHORIZE]) - && $_GET[self::PARAM_AUTHORIZE] === self::$_config['apiUrl'] - ) { - $downloadLink = XenForo_Link::buildAdminLink( - 'full:add-ons/upgrade', - $controllerResponse->params['addOn'], - array( - self::PARAM_DOWNLOAD => self::$_config['apiUrl'] - ) - ); - $downloadLinkJson = json_encode($downloadLink); - $accessTokenParamJson = json_encode(self::PARAM_ACCESS_TOKEN); - - $js = << -var hash = window.location.hash.substr(1); -var regex = /access_token=(.+?)(&|$)/; -var match = hash.match(regex); -if (match) { - var accessToken = match[1]; - var downloadLink = $downloadLinkJson; - window.location = downloadLink + '&' + $accessTokenParamJson + '=' + encodeURIComponent(accessToken); -} - -EOF; - die($js); - } - - if (!empty($_GET[self::PARAM_DOWNLOAD]) - && $_GET[self::PARAM_DOWNLOAD] === self::$_config['apiUrl'] - ) { - $accessToken = ''; - if (!empty($_GET[self::PARAM_ACCESS_TOKEN])) { - $accessToken = $_GET[self::PARAM_ACCESS_TOKEN]; - } - - $addOnId = $controllerResponse->params['addOn']['addon_id']; - $data = self::_fetchData(self::$_config['apiUrl'], array($addOnId), $accessToken); - - if (!empty($data[$addOnId]['links']['content'])) { - $tempFile = DevHelper_Helper_ShippableHelper_TempFile::download($data[$addOnId]['links']['content']); - $xmlPath = self::_updateAddOnFiles($addOnId, $tempFile); - - /** @noinspection BadExpressionStatementJS */ - die(sprintf('', - json_encode(XenForo_Link::buildAdminLink('add-ons/upgrade', array('addon_id' => $addOnId), array( - self::PARAM_IMPORT_XML => self::$_config['apiUrl'], - self::PARAM_IMPORT_XML_PATH => $xmlPath - )))) - ); - } - } - - if (!empty($_GET[self::PARAM_IMPORT_XML]) - && $_GET[self::PARAM_IMPORT_XML] === self::$_config['apiUrl'] - && !empty($_GET[self::PARAM_IMPORT_XML_PATH]) - ) { - $addOnId = $controllerResponse->params['addOn']['addon_id']; - $xmlPath = $_GET[self::PARAM_IMPORT_XML_PATH]; - - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = XenForo_Model::create('XenForo_Model_AddOn'); - $addOnModel->installAddOnXmlFromFile($xmlPath, $addOnId); - - $addOn = $addOnModel->getAddOnById($addOnId); - echo(sprintf('Updated add-on %1$s to v%2$s (#%3$d)', - $addOn['title'], $addOn['version_string'], $addOn['version_id'])); - - /** @noinspection BadExpressionStatementJS */ - die(sprintf('', - json_encode(XenForo_Link::buildAdminLink('full:tools/run-deferred', null, array( - 'redirect' => XenForo_Link::buildAdminLink('full:add-ons') - ))))); - } - - if (!empty($_GET[self::PARAM_IGNORE]) - && $_GET[self::PARAM_IGNORE] === self::$_config['apiUrl'] - ) { - $addOnId = $controllerResponse->params['addOn']['addon_id']; - $data = self::_refreshData(self::$_config['apiUrl'], self::$_config['addOnIds'], false); - if (!empty($data[$addOnId]['version_id'])) { - self::$_config['ignored'][$addOnId] = $data[$addOnId]['version_id']; - self::_saveConfig(self::$_config); - } - - $controllerResponse = new XenForo_ControllerResponse_Redirect(); - $controllerResponse->redirectType = XenForo_ControllerResponse_Redirect::RESOURCE_UPDATED; - $controllerResponse->redirectTarget = XenForo_Link::buildAdminLink('add-ons'); - } - } - - private static function _updateSelf(array $config) - { - $options = XenForo_Application::getOptions(); - - $configOptionId = DevHelper_Helper_ShippableHelper_Updater::getConfigOptionId($config['apiUrl']); - $templateTitle = $configOptionId; - $templateModKey = $configOptionId; - - $configVersion = $config['version']; - $configUpdated = array(); - if ($configVersion === 0) { - $configUpdated[] = '$config'; - } - - if ($configVersion < DevHelper_Helper_ShippableHelper_Updater::$_version) { - if ($configVersion < 2015100121) { - /** @var XenForo_DataWriter_AdminTemplate $templateDw */ - $templateDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate'); - - /** @var XenForo_Model_AdminTemplate $templateModel */ - $templateModel = XenForo_Model::create('XenForo_Model_AdminTemplate'); - $template = $templateModel->getAdminTemplateByTitle($templateTitle); - if (!empty($template)) { - $templateDw->setExistingData($template, true); - } - - $templateDw->bulkSet(array( - 'title' => $templateTitle, - 'template' => self::$_template, - )); - $templateDw->save(); - - $configUpdated[] = '$templateDw'; - } - - if ($configVersion < 2015100107) { - /** @var XenForo_DataWriter_AdminTemplateModification $templateModDw */ - $templateModDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplateModification'); - - /** @var XenForo_Model_AdminTemplateModification $templateModModel */ - $templateModModel = XenForo_Model::create('XenForo_Model_AdminTemplateModification'); - $templateMod = $templateModModel->getModificationByKey($templateModKey); - if (!empty($templateMod)) { - $templateModDw->setExistingData($templateMod, true); - } - - $templateModDw->bulkSet(array( - 'template' => 'content_header', - 'modification_key' => $templateModKey, - 'description' => $config['apiUrl'], - 'action' => 'preg_replace', - 'find' => '#^.+$#s', - 'replace' => '$0' . str_replace('md5', md5($config['apiUrl']), self::$_templateMod), - )); - $templateModDw->save(); - - $configUpdated[] = '$templateModDw'; - } - - $config['version'] = DevHelper_Helper_ShippableHelper_Updater::$_version; - $configUpdated[] = '$config["version"]'; - } - - $addOnIdsUpdated = false; - foreach ($GLOBALS[DevHelper_Helper_ShippableHelper_Updater::KEY][$config['apiUrl']]['addOns'] as $addOnId => $enabled) { - if (!in_array($addOnId, $config['addOnIds'], true)) { - $config['addOnIds'][] = $addOnId; - $addOnIdsUpdated = true; - } - } - if ($addOnIdsUpdated) { - sort($config['addOnIds']); - $configUpdated[] = '$config["addOnIds"]'; - } - - if (count($configUpdated) > 0) { - /** @var XenForo_DataWriter_Option $optionDw */ - $optionDw = XenForo_DataWriter::create('XenForo_DataWriter_Option'); - if ($configVersion > 0) { - $optionDw->setExistingData($configOptionId); - } - $optionDw->bulkSet(array( - 'option_id' => $configOptionId, - 'option_value' => $config, - 'default_value' => 'a:0:{}', - 'edit_format' => 'template', - 'edit_format_params' => $templateTitle, - 'data_type' => 'array', - 'sub_options' => '*', - )); - $optionDw->setRelations(array( - 'debug' => 9999, - )); - $optionDw->setExtraData(XenForo_DataWriter_Option::DATA_TITLE, 'Add-on Updates' - . (self::$_isBeta ? ' (BETA)' : '')); - $optionDw->setExtraData(XenForo_DataWriter_Option::DATA_EXPLAIN, 'Turn on this option if you want to' - . ' check for add-on updates from ' - . $config['apiUrl'] . ' regularly. If you want to perform update check immediately, click here.'); - $optionDw->save(); - $options->set($configOptionId, $config); - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s): $configVersion=%d,' - . ' self::$_version=%d, $configUpdated=%s', - __METHOD__, $config['apiUrl'], var_export($configVersion, true), - var_export(DevHelper_Helper_ShippableHelper_Updater::$_version, true), - var_export($configUpdated, true))); - } - } - - self::$_config = $config; - } - - private static function _updateAddOnFiles($addOnId, $tempFile) - { - $tempDir = $tempFile . '_extracted'; - - XenForo_Helper_File::createDirectory($tempDir, false); - XenForo_Helper_File::makeWritableByFtpUser($tempDir); - - $decompress = new Zend_Filter_Decompress(array( - 'adapter' => 'Zip', - 'options' => array('target' => $tempDir) - )); - - if (!$decompress->filter($tempFile)) { - throw new XenForo_Exception('Unable to extract add-on package.', true); - } - - $uploadDir = sprintf('%s/upload', $tempDir); - if (!is_dir($uploadDir)) { - throw new XenForo_Exception('Unsupported add-on package (no "upload" directory found).', true); - } - - $xfDir = dirname(XenForo_Autoloader::getInstance()->getRootDir()); - $files = self::_verifyAddOnFiles($uploadDir, $xfDir); - - $xmlPath = self::_findXmlPath($addOnId, $tempDir, $xfDir, $files); - - self::_moveAddOnFiles($uploadDir, $xfDir, $files); - - return $xmlPath; - } - - private static function _verifyAddOnFiles($packageDir, $xfDir, $relativePath = null) - { - $files = array(); - - $dir = sprintf('%s/%s', $packageDir, $relativePath); - $entries = scandir($dir); - $subDirs = array(); - - foreach ($entries as $entry) { - if (substr($entry, 0, 1) === '.') { - // ignore hidden files - continue; - } - - if ($relativePath !== null) { - $fileRelativePath = sprintf('%s/%s', $relativePath, $entry); - } else { - $fileRelativePath = $entry; - } - - if (is_file(sprintf('%s/%s', $packageDir, $fileRelativePath))) { - $files[] = $fileRelativePath; - - $fileSystemPath = sprintf('%s/%s', $xfDir, $fileRelativePath); - if (is_file($fileSystemPath)) { - if (!is_writable($fileSystemPath)) { - throw new XenForo_Exception('File is not writable: ' . $fileSystemPath, true); - } - } elseif (is_dir($fileSystemPath)) { - throw new XenForo_Exception('File/directory conflict: ' . $fileSystemPath, true); - } else { - $parentOfFileSystemPath = dirname($fileSystemPath); - if (is_dir($parentOfFileSystemPath)) { - if (!is_writable($parentOfFileSystemPath)) { - throw new XenForo_Exception('Directory is not writable: ' - . $parentOfFileSystemPath, true); - } - } else { - if (!XenForo_Helper_File::createDirectory($parentOfFileSystemPath)) { - throw new XenForo_Exception('Directory cannot be created: ' - . $parentOfFileSystemPath, true); - } - } - } - } else { - $subDirs[] = $fileRelativePath; - } - } - - foreach ($subDirs as $subDir) { - $files = array_merge($files, self::_verifyAddOnFiles($packageDir, $xfDir, $subDir)); - } - - return $files; - } - - private static function _moveAddOnFiles($packageDir, $xfDir, array $files) - { - foreach ($files as $file) { - $packagePath = sprintf('%s/%s', $packageDir, $file); - $systemPath = sprintf('%s/%s', $xfDir, $file); - - if (!XenForo_Helper_File::safeRename($packagePath, $systemPath)) { - throw new XenForo_Exception('File cannot be updated: ' . $file); - } - } - } - - private static function _findXmlPath($addOnId, $tempDir, $xfDir, array $files) - { - foreach ($files as $file) { - $fileName = basename($file); - if (preg_match('#^addon-(?.+)\.xml$#', $fileName, $matches)) { - if ($addOnId === $matches['id']) { - return sprintf('%s/%s', $xfDir, $file); - } - } - } - - $entries = scandir($tempDir); - foreach ($entries as $entry) { - if (preg_match('#^addon-(?.+)\.xml$#', $entry, $matches)) { - if ($addOnId === $matches['id']) { - return sprintf('%s/%s', $tempDir, $entry); - } - } - } - - throw new XenForo_Exception('Unsupported add-on package (no xml found).', true); - } - - public static function _uninstallSelf($apiUrl) - { - $configOptionId = DevHelper_Helper_ShippableHelper_Updater::getConfigOptionId($apiUrl); - $templateTitle = $configOptionId; - $templateModKey = $configOptionId; - - try { - XenForo_Db::beginTransaction(); - - /** @var XenForo_Model_AdminTemplate $templateModel */ - $templateModel = XenForo_Model::create('XenForo_Model_AdminTemplate'); - $template = $templateModel->getAdminTemplateByTitle($templateTitle); - if (!empty($template)) { - /** @var XenForo_DataWriter_AdminTemplate $templateDw */ - $templateDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate'); - $templateDw->setExistingData($template, true); - $templateDw->delete(); - } - - - /** @var XenForo_Model_AdminTemplateModification $templateModModel */ - $templateModModel = XenForo_Model::create('XenForo_Model_AdminTemplateModification'); - $templateMod = $templateModModel->getModificationByKey($templateModKey); - if (!empty($templateMod)) { - /** @var XenForo_DataWriter_AdminTemplateModification $templateModDw */ - $templateModDw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplateModification'); - $templateModDw->setExistingData($templateMod, true); - $templateModDw->delete(); - } - - /** @var XenForo_DataWriter_Option $optionDw */ - $optionDw = XenForo_DataWriter::create('XenForo_DataWriter_Option'); - $optionDw->setExistingData($configOptionId); - $optionDw->delete(); - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s): ok', - __METHOD__, $apiUrl)); - } - - XenForo_Db::commit(); - } catch (XenForo_Exception $e) { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s): %s', - __METHOD__, $apiUrl, $e->__toString())); - } - - XenForo_Db::rollback(); - } - } - - private static function _refreshData($apiUrl, array $addOnIds, $forceRefresh) - { - $data = ($forceRefresh ? null : self::_getCache($apiUrl)); - if (empty($data) - || $data['version'] < DevHelper_Helper_ShippableHelper_Updater::$_version - || $data['timestamp'] < XenForo_Application::$time - 86400 - ) { - $data = array( - 'version' => DevHelper_Helper_ShippableHelper_Updater::$_version, - 'timestamp' => time(), - 'json' => self::_fetchData($apiUrl, $addOnIds), - ); - - self::_setCache($apiUrl, $data); - } - - return $data['json']; - } - - private static function _fetchData($url, array $addOnIds, $accessToken = '') - { - if (empty($addOnIds)) { - return array(); - } - - $url .= sprintf('%s_version=%d', ((strpos($url, '?') === false) ? '?' : '&'), - DevHelper_Helper_ShippableHelper_Updater::$_version); - if (!empty($accessToken)) { - $url .= sprintf('&oauth_token=%s', rawurlencode($accessToken)); - } - foreach ($addOnIds as $addOnId) { - $url .= sprintf('&ids[]=%s', rawurlencode($addOnId)); - } - - $client = XenForo_Helper_Http::getClient($url); - - try { - $response = $client->request('GET'); - - $responseStatus = $response->getStatus(); - $responseBody = $response->getBody(); - } catch (Exception $e) { - $responseStatus = 503; - $responseBody = $e->getMessage(); - } - - $json = null; - if ($responseStatus === 200) { - $json = @json_decode($responseBody, true); - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($url=%s): status=%d, json=%s', - __METHOD__, $url, - var_export($responseStatus, true), var_export($json, true))); - } - } else { - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($url=%s): status=%d, body=%s', - __METHOD__, $url, - var_export($responseStatus, true), var_export($responseBody, true))); - } - } - - return $json; - } - - private static function _getCache($apiUrl) - { - /** @var XenForo_Model_DataRegistry $dataRegistryModel */ - $dataRegistryModel = XenForo_Model::create('XenForo_Model_DataRegistry'); - $data = $dataRegistryModel->get(DevHelper_Helper_ShippableHelper_Updater::KEY); - - if (!empty($data) - && isset($data[$apiUrl]) - ) { - return $data[$apiUrl]; - } - - return array(); - } - - private static function _setCache($apiUrl, array $thisData) - { - /** @var XenForo_Model_DataRegistry $dataRegistryModel */ - $dataRegistryModel = XenForo_Model::create('XenForo_Model_DataRegistry'); - $data = $dataRegistryModel->get(DevHelper_Helper_ShippableHelper_Updater::KEY); - if (empty($data)) { - $data = array(); - } - $data[$apiUrl] = $thisData; - $dataRegistryModel->set(DevHelper_Helper_ShippableHelper_Updater::KEY, $data); - return true; - } - - private static function _saveConfig(array $config) - { - $configOptionId = DevHelper_Helper_ShippableHelper_Updater::getConfigOptionId($config['apiUrl']); - - /** @var XenForo_DataWriter_Option $optionDw */ - $optionDw = XenForo_DataWriter::create('XenForo_DataWriter_Option'); - $optionDw->setExistingData($configOptionId); - $optionDw->set('option_value', $config); - - if ($optionDw->save()) { - XenForo_Application::getOptions()->set($configOptionId, $config); - - if (XenForo_Application::debugMode()) { - XenForo_Helper_File::log(__CLASS__, sprintf('%s($apiUrl=%s)', - __METHOD__, $config['apiUrl'])); - } - - return true; - } - - return false; - } - - private static function _getEnabledAddOnIds($addOnIds) - { - $xenAddOns = XenForo_Application::get('addOns'); - $enabledIds = array(); - foreach ($addOnIds as $configAddOnId) { - if (isset($xenAddOns[$configAddOnId])) { - $enabledIds[] = $configAddOnId; - } - } - - return $enabledIds; - } - - private static $_template = ' - - - - - {$configAddOnId} - - - - - - - - {xen:raw $preparedOption.explain} - Supported add-ons: {$addOnListStr} - - - - {xen:raw $editLink} - - - - - - - - -'; - - private static $_templateMod = ' - -

{xen:raw $_md5.message}

-
'; - - private static $_config = null; -} \ No newline at end of file diff --git a/library/DevHelper/Helper/Template.php b/library/DevHelper/Helper/Template.php deleted file mode 100644 index a6ea331..0000000 --- a/library/DevHelper/Helper/Template.php +++ /dev/null @@ -1,56 +0,0 @@ -getClassPrefix() . '_'; - $prefixLength = strlen($prefix); - - foreach (self::$_foundXfcpClasses as $clazz => $paths) { - if (substr($clazz, 0, $prefixLength) !== $prefix) { - // not prefixed with our add-on ID, ignore it - continue; - } - - $clazzWithoutPrefix = substr($clazz, $prefixLength); - $realClazz = $clazzWithoutPrefix; - $realPath = DevHelper_Generator_File::getClassPath($realClazz); - if (!file_exists($realPath)) { - // the real class could not be found, hmm... - // try to replace 'Extend_' with 'XenForo_' to support our legacy add-ons - if (substr($realClazz, 0, 7) !== 'Extend_') { - // no hope - continue; - } - - $realClazz = 'XenForo_' . substr($realClazz, 7); - $realPath = DevHelper_Generator_File::getClassPath($realClazz); - if (!file_exists($realPath)) { - // not found either... bye! - continue; - } - } - - if (self::generateXfcpClass($clazz, $realClazz, $config)) { - echo "Generated XFCP_{$clazz} ({$realClazz})\n"; - } - } - } - - public static function generateOurClass($clazz, DevHelper_Config_Base $config) - { - $path = DevHelper_Generator_File::getClassPath($clazz, $config); - $contents = <<getClassPrefix(), $config->getClassPrefix() . '_DevHelper_XFCP', $clazz); - $ghostPath = DevHelper_Generator_File::getClassPath($ghostClazz, $config); - if (file_exists($ghostPath)) { - // ghost file exists, yay! - return true; - } - - $ghostContents = "[^\s]+)\s#'; - while (true) { - if (preg_match($extendsXfcp, $contents, $matches, PREG_OFFSET_CAPTURE, $offset)) { - $clazz = $matches['clazz'][0]; - $offset = $matches[0][1] + strlen($matches[0][0]); - self::$_foundXfcpClasses[$clazz][$path] = true; - } else { - break; - } - } - } -} diff --git a/library/DevHelper/Installer.php b/library/DevHelper/Installer.php deleted file mode 100644 index 079832c..0000000 --- a/library/DevHelper/Installer.php +++ /dev/null @@ -1,107 +0,0 @@ -setupAutoloader($fileDir . '/library'); - XenForo_Application::initialize($fileDir . '/library', $fileDir); - - $dependencies = new XenForo_Dependencies_Public(); - $dependencies->preLoadData(); - - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = XenForo_Model::create('XenForo_Model_AddOn'); - - $devHelperAddOn = $addOnModel->getAddOnById('devHelper'); - if (!empty($devHelperAddOn)) { - die("DevHelper add-on has already been installed.\n"); - } - - $addOnModel->installAddOnXmlFromFile('library/DevHelper/addon-devHelper.xml'); - die("DevHelper add-on has been installed successfully.\n"); -} - -class DevHelper_Installer -{ - /* Start auto-generated lines of code. Change made will be overwriten... */ - - protected static $_tables = array(); - protected static $_patches = array(); - - public static function install($existingAddOn, $addOnData) - { - $db = XenForo_Application::get('db'); - - foreach (self::$_tables as $table) { - $db->query($table['createQuery']); - } - - foreach (self::$_patches as $patch) { - $tableExisted = $db->fetchOne($patch['showTablesQuery']); - if (empty($tableExisted)) { - continue; - } - - $existed = $db->fetchOne($patch['showColumnsQuery']); - if (empty($existed)) { - $db->query($patch['alterTableAddColumnQuery']); - } - } - - self::installCustomized($existingAddOn, $addOnData); - } - - public static function uninstall() - { - $db = XenForo_Application::get('db'); - - foreach (self::$_patches as $patch) { - $tableExisted = $db->fetchOne($patch['showTablesQuery']); - if (empty($tableExisted)) { - continue; - } - - $existed = $db->fetchOne($patch['showColumnsQuery']); - if (!empty($existed)) { - $db->query($patch['alterTableDropColumnQuery']); - } - } - - foreach (self::$_tables as $table) { - $db->query($table['dropQuery']); - } - - self::uninstallCustomized(); - } - - /* End auto-generated lines of code. Feel free to make changes below */ - - public static function installCustomized($existingAddOn, $addOnData) - { - // customized install script goes here - } - - public static function uninstallCustomized() - { - // customized uninstall script goes here - } - - public static function checkAddOnVersion() - { - if (XenForo_Application::isRegistered('addOns')) { - $addOns = XenForo_Application::get('addOns'); - $versionId = $addOns['devHelper']; - - $xml = file_get_contents(dirname(__FILE__) . '/addon-DevHelper.xml'); - if (preg_match('#version_id="(?\d+)"#', $xml, $matches)) { - if ($versionId < $matches['id']) { - return false; - } - } - } - - return true; - } -} diff --git a/library/DevHelper/Listener.php b/library/DevHelper/Listener.php deleted file mode 100755 index 770a5ca..0000000 --- a/library/DevHelper/Listener.php +++ /dev/null @@ -1,175 +0,0 @@ - $styleDate) { - // consider this is a change, start updating the template - $maxTemplateDate = max($maxTemplateDate, $templateDate); - - $templateId = DevHelper_Helper_Template::getTemplateIdFromFilePath($templateFile); - if (empty($templateId)) { - continue; - } - - $templateText = file_get_contents($templateFile); - - $properties = $propertyModel->keyPropertiesByName($propertyModel->getEffectiveStylePropertiesInStyle(0)); - $propertyChanges = $propertyModel->translateEditorPropertiesToArray( - $templateText, - $templateText, - $properties - ); - - /** @var XenForo_DataWriter_Template $dw */ - $dw = XenForo_DataWriter::create('XenForo_DataWriter_Template'); - $dw->setExistingData($templateId); - $dw->set('template', $templateText); - - if ($dw->hasErrors()) { - throw new XenForo_Exception(implode(', ', $dw->getErrors())); - } - - if ($dw->hasChanges()) { - $dw->reparseTemplate(); - - $dw->save(); - - $propertyModel->saveStylePropertiesInStyleFromTemplate(0, $propertyChanges, $properties); - - $templatesUpdated[] = $dw->get('title'); - } - } - } - - if (!empty($maxTemplateDate)) { - /** @var XenForo_Model_Style $styleModel */ - $styleModel = XenForo_Model::create('XenForo_Model_Style'); - $styleModel->updateAllStylesLastModifiedDate($maxTemplateDate); - } - } - } - - public static function template_hook($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template) - { - switch ($hookName) { - case 'devhelper_devhelper_helper_addon_unit': - self::_filterDisabledAddOnOptions($contents); - break; - } - } - - protected static function _filterDisabledAddOnOptions(&$html) - { - $offset = 0; - - $addOns = XenForo_Application::get('addOns'); - - while (true) { - if (preg_match( - '/\s+<\/optgroup>/i', - $html, - $matches, - PREG_OFFSET_CAPTURE, - $groupOffset - )) { - $groupOffset = $matches[0][1] + 1; - $length = strlen($matches[0][0]); - - $html = substr_replace($html, '', $groupOffset - 1, $length); - $groupOffset--; - } else { - break; - } - } - } - - public static function file_health_check(XenForo_ControllerAdmin_Abstract $controller, array &$hashes) - { - $hashes += DevHelper_FileSums::getHashes(); - } -} diff --git a/library/DevHelper/Model/Config.php b/library/DevHelper/Model/Config.php deleted file mode 100755 index 1e1ddb3..0000000 --- a/library/DevHelper/Model/Config.php +++ /dev/null @@ -1,48 +0,0 @@ -upgradeConfig(); - - if (!empty($created) OR !empty($upgraded)) { - $this->saveAddOnConfig($addOn, $config); - } - - return $config; - } - - public function saveAddOnConfig($addOn, DevHelper_Config_Base $config) - { - $className = DevHelper_Generator_File::getClassName($addOn['addon_id'], 'DevHelper_Config'); - DevHelper_Generator_File::writeClass($className, $config->outputSelf()); - } -} diff --git a/library/DevHelper/Router.php b/library/DevHelper/Router.php deleted file mode 100644 index 7b9418e..0000000 --- a/library/DevHelper/Router.php +++ /dev/null @@ -1,154 +0,0 @@ -setupAutoloader($fileDir . '/xenforo/library'); - } - - public static function locateCached($fullPath) - { - $key = basename($fullPath) . md5($fullPath); - $cached = apcu_fetch($key); - $located = null; - $success = false; - if (is_array($cached) - && $cached['fullPath'] === $fullPath) { - $located = $cached['located']; - } - - if (empty($located)) { - $located = static::locate($fullPath, $success); - } - - if ($success) { - $cacheEntry = array( - 'fullPath' => $fullPath, - 'located' => $located, - ); - - apcu_store($key, $cacheEntry); - } - - return $located; - } - - public static function locate($fullPath, &$success = null) - { - if (file_exists($fullPath)) { - $success = true; - return $fullPath; - } - - list($xenforoDir, $addOnPaths) = static::getLocatePaths(); - $shortened = preg_replace( - '#^' . preg_quote($xenforoDir, '#') . '#', - '', - $fullPath - ); - - foreach ($addOnPaths as $addOnPath) { - $candidatePath = $addOnPath . $shortened; - if (file_exists($candidatePath)) { - $success = true; - return $candidatePath; - } - } - - return $fullPath; - } - - public static function getLocatePaths() - { - static $xenforoDir = null; - static $addOnPaths = null; - - if ($addOnPaths === null) { - $routerPhp = $_SERVER['DEVHELPER_ROUTER_PHP']; - $routerPhpDir = dirname($routerPhp); - $xenforoDir = sprintf('%s/xenforo', $routerPhpDir); - $addOnPaths = array($routerPhpDir); - - $txtPath = sprintf('%s/internal_data/addons.txt', $xenforoDir); - $lines = array(); - if (file_exists($txtPath)) { - $lines = file($txtPath); - } - - foreach ($lines as $line) { - $line = trim($line); - if (strlen($line) === 0) { - continue; - } - - $addOnPaths[] = sprintf('%s/%s', $routerPhpDir, $line); - } - } - - return array($xenforoDir, $addOnPaths); - } -} diff --git a/library/DevHelper/ViewAdmin/AddOn/DataManager.php b/library/DevHelper/ViewAdmin/AddOn/DataManager.php deleted file mode 100755 index db01efd..0000000 --- a/library/DevHelper/ViewAdmin/AddOn/DataManager.php +++ /dev/null @@ -1,18 +0,0 @@ -_params['dataClasses'] as &$dataClass) { - $dataClass['fieldsList'] = implode(', ', array_keys($dataClass['fields'])); - } - - if (!empty($this->_params['focusedDataClass'])) { - $this->_params['focusedDataClass']['sqlCreate'] = DevHelper_Generator_Db::createTable( - $this->_params['config'], - $this->_params['focusedDataClass'] - ); - } - } -} diff --git a/library/DevHelper/XenForo/CodeEvent.php b/library/DevHelper/XenForo/CodeEvent.php deleted file mode 100644 index e108e10..0000000 --- a/library/DevHelper/XenForo/CodeEvent.php +++ /dev/null @@ -1,113 +0,0 @@ -getRootDir() . '/library/XenForo/CodeEvent.php'); -$contents = substr($originalContents, strpos($originalContents, 'autoload('DevHelper_Installer'); - } - - $addOn = $addOnModel->getAddOnById('devHelper'); - if (!empty($addOn)) { - /** @var XenForo_DataWriter_AddOn $addOnDw */ - $addOnDw = XenForo_DataWriter::create('XenForo_DataWriter_AddOn'); - $addOnDw->setExistingData($addOn); - $addOnDw->set('active', 1); - $addOnDw->save(); - - $message = 'Re-enabled DevHelper add-on.'; - } else { - $xmlPath = 'library/DevHelper/addon-devHelper.xml'; - if (!file_exists($xmlPath)) { - die(sprintf('XML path (%s) does not exist', $xmlPath)); - } - $addOnModel->installAddOnXmlFromFile($xmlPath); - - $message = 'Installed DevHelper add-on.'; - } - - /** @var XenForo_FrontController $fc */ - $fc = $args[0]; - $redirect = $fc->getRequest()->getRequestUri(); - - die(sprintf( - 'alert(%s);window.location = %s;', - json_encode($message), - json_encode(XenForo_Link::buildAdminLink('full:tools/run-deferred', null, array( - 'redirect' => $redirect, - ))) - )); - } - } - - return parent::fire($event, $args, $hint); - } - - public static $measuredTime = array('events' => array(), 'callbacks' => array()); - - public static function DevHelper_measureCallbackTime($event, $callback, $args) - { - $startTime = microtime(true); - $result = call_user_func_array($callback, $args); - $elapsed = microtime(true) - $startTime; - - if (!isset(self::$measuredTime['events'][$event])) { - self::$measuredTime['events'][$event] = array( - 'count' => 0, - 'elapsed' => 0, - ); - } - self::$measuredTime['events'][$event]['count']++; - self::$measuredTime['events'][$event]['elapsed'] += $elapsed; - - $callbackSafe = $callback; - if (!is_string($callbackSafe)) { - $callbackSafe = XenForo_Helper_Php::safeSerialize($callback); - } - if (!isset(self::$measuredTime['callbacks'][$callbackSafe])) { - self::$measuredTime['callbacks'][$callbackSafe] = array( - 'count' => 0, - 'elapsed' => 0, - ); - } - self::$measuredTime['callbacks'][$callbackSafe]['count']++; - self::$measuredTime['callbacks'][$callbackSafe]['elapsed'] += $elapsed; - - return $result; - } -} - -eval('abstract class XenForo_CodeEvent extends DevHelper_XenForo_CodeEvent {}'); - -if (false) { - class _XenForo_CodeEvent extends XenForo_CodeEvent - { - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/AddOn.php b/library/DevHelper/XenForo/ControllerAdmin/AddOn.php deleted file mode 100755 index b6fa361..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/AddOn.php +++ /dev/null @@ -1,387 +0,0 @@ -getHelper('DevHelper_ControllerHelper_AddOn'); - $helper->selfCheck(); - - $response = parent::actionIndex(); - - if ($response instanceof XenForo_ControllerResponse_View) { - uasort($response->params['addOns'], create_function( - '$a, $b', - 'if ($a["active"] == $b["active"]) { return strcmp($a["title"], $b["title"]); } else { if ($a["active"]) return -1; else return 1; }' - )); - } - - return $response; - } - - public function actionInstall() - { - if (!$this->isConfirmedPost() - && !empty($_SERVER['DEVHELPER_ROUTER_PHP']) - ) { - exec('/usr/local/bin/find-addons.sh'); - apcu_clear_cache(); - } - - return parent::actionInstall(); - } - - public function actionSave() - { - $GLOBALS[DevHelper_Listener::XENFORO_CONTROLLERADMIN_ADDON_SAVE] = $this; - - $response = parent::actionSave(); - - if ($response instanceof XenForo_ControllerResponse_Redirect) { - if (!empty($this->_DevHelper_actionSave_addOnIdChanged)) { - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('add-ons/file-export', $this->_DevHelper_actionSave_addOnIdChanged) - ); - } - } - - return $response; - } - - public function DevHelper_actionSave(XenForo_DataWriter_AddOn $addOnDw) - { - if ($addOnDw->isUpdate() AND $addOnDw->isChanged('version_id')) { - $this->_DevHelper_actionSave_addOnIdChanged = $addOnDw->getMergedData(); - } - } - - public function actionDataManager() - { - $addOnId = $this->_input->filterSingle('addon_id', XenForo_Input::STRING); - $addOn = $this->_getAddOnOrError($addOnId); - - $config = $this->_getConfigModel()->loadAddOnConfig($addOn); - - $viewParams = array( - 'addOn' => $addOn, - 'config' => $config, - 'dataClasses' => $config->getDataClasses(), - ); - - $dataClassName = $this->_input->filterSingle('dataClass', XenForo_Input::STRING); - if (!empty($dataClassName) AND $config->checkDataClassExists($dataClassName)) { - $viewParams['focusedDataClass'] = $config->getDataClass($dataClassName); - } - - return $this->responseView( - 'DevHelper_ViewAdmin_AddOn_DataManager', - 'devhelper_addon_data_manager', - $viewParams - ); - } - - public function actionGenerateFile() - { - $addOnId = $this->_input->filterSingle('addon_id', XenForo_Input::STRING); - $addOn = $this->_getAddOnOrError($addOnId); - - $config = $this->_getConfigModel()->loadAddOnConfig($addOn); - $dataClassName = $this->_input->filterSingle('dataClass', XenForo_Input::STRING); - if (!empty($dataClassName) AND $config->checkDataClassExists($dataClassName)) { - $dataClass = $config->getDataClass($dataClassName); - $file = $this->_input->filterSingle('file', XenForo_Input::STRING); - - switch ($file) { - case 'data_writer': - case 'model': - case 'route_prefix_admin': - case 'controller_admin': - case 'installer': - $suffix = str_replace(' ', '', ucwords(str_replace('_', ' ', $file))); - return call_user_func(array( - $this, - '_actionGenerate' . $suffix - ), $addOn, $config, $dataClass); - } - } - - return $this->responseNoPermission(); - } - - protected function _actionGenerateDataWriter(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - list($className, $contents) = DevHelper_Generator_Code_DataWriter::generate($addOn, $config, $dataClass); - $path = DevHelper_Generator_File::writeClass($className, $contents); - - $config->updateDataClassFile($dataClass['name'], 'data_writer', $className, $path); - $this->_getConfigModel()->saveAddOnConfig($addOn, $config); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::RESOURCE_CREATED, - XenForo_Link::buildAdminLink( - 'add-ons/data-manager', - $addOn, - array('dataClass' => $dataClass['name']) - ) - ); - } - - protected function _actionGenerateModel(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - list($className, $contents) = DevHelper_Generator_Code_Model::generate($addOn, $config, $dataClass); - $path = DevHelper_Generator_File::writeClass($className, $contents); - - $config->updateDataClassFile($dataClass['name'], 'model', $className, $path); - $this->_getConfigModel()->saveAddOnConfig($addOn, $config); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::RESOURCE_CREATED, - XenForo_Link::buildAdminLink( - 'add-ons/data-manager', - $addOn, - array('dataClass' => $dataClass['name']) - ) - ); - } - - protected function _actionGenerateRoutePrefixAdmin(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $routePrefix = $this->_input->filterSingle('route_prefix', XenForo_Input::STRING); - $controller = $this->_input->filterSingle('controller', XenForo_Input::STRING); - $majorSection = $this->_input->filterSingle('major_section', XenForo_Input::STRING); - - if (empty($routePrefix) OR empty($controller)) { - $viewParams = array( - 'addOn' => $addOn, - 'dataClass' => $dataClass, - 'routePrefix' => $routePrefix ?: DevHelper_Generator_Code_RoutePrefixAdmin::getRoutePrefix( - $addOn, - $config, - $dataClass - ), - 'controller' => $controller ?: DevHelper_Generator_Code_ControllerAdmin::getClassName( - $addOn, - $config, - $dataClass - ), - 'majorSection' => $majorSection, - ); - - return $this->responseView( - 'DevHelper_ViewAdmin_AddOn_GenerateRoutePrefixAdmin', - 'devhelper_addon_generate_route_prefix_admin', - $viewParams - ); - } else { - list($className, $contents) = DevHelper_Generator_Code_RoutePrefixAdmin::generate( - $addOn, - $config, - $dataClass, - array( - 'routePrefix' => $routePrefix, - 'controller' => $controller, - 'majorSection' => $majorSection, - ) - ); - $path = DevHelper_Generator_File::writeClass($className, $contents); - - $config->updateDataClassFile($dataClass['name'], 'route_prefix_admin', $className, $path); - $this->_getConfigModel()->saveAddOnConfig($addOn, $config); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::RESOURCE_CREATED, - XenForo_Link::buildAdminLink( - 'add-ons/data-manager', - $addOn, - array('dataClass' => $dataClass['name']) - ) - ); - } - } - - protected function _actionGenerateControllerAdmin(array $addOn, DevHelper_Config_Base $config, array $dataClass) - { - $routePrefix = $this->_input->filterSingle('route_prefix', XenForo_Input::STRING); - $controller = $this->_input->filterSingle('controller', XenForo_Input::STRING); - - if (empty($routePrefix) OR empty($controller)) { - $viewParams = array( - 'addOn' => $addOn, - 'dataClass' => $dataClass, - 'routePrefix' => $routePrefix ?: DevHelper_Generator_Code_RoutePrefixAdmin::getRoutePrefix( - $addOn, - $config, - $dataClass - ), - 'controller' => $controller ?: DevHelper_Generator_Code_ControllerAdmin::getClassName( - $addOn, - $config, - $dataClass - ), - ); - - return $this->responseView( - 'DevHelper_ViewAdmin_AddOn_GenerateControllerAdmin', - 'devhelper_addon_generate_controller_admin', - $viewParams - ); - } else { - list($className, $contents) = DevHelper_Generator_Code_ControllerAdmin::generate( - $addOn, - $config, - $dataClass, - array( - 'routePrefix' => $routePrefix, - 'controller' => $controller, - ) - ); - $path = DevHelper_Generator_File::writeClass($className, $contents); - - $config->updateDataClassFile($dataClass['name'], 'controller_admin', $className, $path); - $this->_getConfigModel()->saveAddOnConfig($addOn, $config); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::RESOURCE_CREATED, - XenForo_Link::buildAdminLink( - 'add-ons/data-manager', - $addOn, - array('dataClass' => $dataClass['name']) - ) - ); - } - } - - public function actionGenerateInstaller() - { - $addOnId = $this->_input->filterSingle('addon_id', XenForo_Input::STRING); - $addOn = $this->_getAddOnOrError($addOnId); - - $config = $this->_getConfigModel()->loadAddOnConfig($addOn); - - list($className, $contents) = DevHelper_Generator_Code_Installer::generate($addOn, $config); - DevHelper_Generator_File::writeClass($className, $contents, $config); - - $dw = XenForo_DataWriter::create('XenForo_DataWriter_AddOn'); - $dw->setExistingData($addOn); - $dw->set('install_callback_class', $className); - $dw->set('install_callback_method', 'install'); - $dw->set('uninstall_callback_class', $className); - $dw->set('uninstall_callback_method', 'uninstall'); - $dw->save(); - - $xmlPath = DevHelper_Generator_File::getAddOnXmlPath($addOn, null, $config); - $this->_getAddOnModel()->getAddOnXml($addOn)->save($xmlPath); - - if ($this->_input->filterSingle('run', XenForo_Input::UINT)) { - call_user_func(array( - $className, - 'install' - ), $dw->getMergedData(), $dw->getMergedData()); - } - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::RESOURCE_CREATED, - XenForo_Link::buildAdminLink('add-ons/data-manager', $addOn) - ); - } - - public function actionFileExport() - { - $addOnId = $this->_input->filterSingle('addon_id', XenForo_Input::STRING); - $addOn = $this->_getAddOnOrError($addOnId); - - $config = $this->_getConfigModel()->loadAddOnConfig($addOn); - - $exportPath = $config->getExportPath(); - - if ($exportPath === false) { - return $this->responseNoPermission(); - } - - DevHelper_Helper_Phrase::startLookingForPhraseTitles(); - DevHelper_Helper_Xfcp::startLookingForXfcpClasses(); - - echo '
';
-
-        DevHelper_Generator_File::fileExport($addOn, $config, $exportPath);
-
-        /** @var XenForo_Model_Template $templateModel */
-        $templateModel = $this->getModelFromCache('XenForo_Model_Template');
-        $templates = $templateModel->getMasterTemplatesInAddOn($addOn['addon_id']);
-        foreach ($templates AS $template) {
-            /** @var DevHelper_XenForo_DataWriter_Template $dw */
-            $dw = XenForo_DataWriter::create('XenForo_DataWriter_Template');
-            $dw->setExistingData($template, true);
-
-            if ($dw->DevHelper_saveTemplate()) {
-                echo "Saved template {$template['title']}\n";
-            }
-        }
-
-        /** @var XenForo_Model_Phrase $phraseModel */
-        $phraseModel = $this->getModelFromCache('XenForo_Model_Phrase');
-        $phrases = $phraseModel->getMasterPhrasesInAddOn($addOnId);
-        DevHelper_Helper_Phrase::finishLookingForPhraseTitles($phrases, $phraseModel);
-        DevHelper_Helper_Xfcp::finishLookingForXfcpClasses($addOn, $config);
-
-        echo '
'; - - die('Done'); - } - - public function actionSwitchContext() - { - $addOnId = $this->_input->filterSingle('addon_id', XenForo_Input::STRING); - $targetAddOn = $this->_getAddOnOrError($addOnId); - - $targetAddOnDw = XenForo_DataWriter::create('XenForo_DataWriter_AddOn'); - $targetAddOnDw->setExistingData($targetAddOn, true); - $targetAddOnDw->set('active', 1); - $targetAddOnDw->save(); - - DevHelper_Generator_Code_XenForoConfig::updateConfig('development.default_addon', $targetAddOn['addon_id']); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('add-ons') - ); - } - - public function actionAllOff() - { - $addOns = $this->_getAddOnModel()->getAllAddOns(); - - foreach ($addOns as $addOn) { - if (empty($addOn['active'])) { - continue; - } - - if ($addOn['addon_id'] == 'devHelper') { - continue; - } - - $addOnDw = XenForo_DataWriter::create('XenForo_DataWriter_AddOn'); - $addOnDw->setExistingData($addOn, true); - $addOnDw->set('active', 0); - $addOnDw->save(); - } - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('add-ons') - ); - } - - /** - * @return DevHelper_Model_Config - */ - protected function _getConfigModel() - { - /** @noinspection PhpIncompatibleReturnTypeInspection */ - return $this->getModelFromCache('DevHelper_Model_Config'); - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/AdminTemplateModification.php b/library/DevHelper/XenForo/ControllerAdmin/AdminTemplateModification.php deleted file mode 100644 index 1a75f99..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/AdminTemplateModification.php +++ /dev/null @@ -1,21 +0,0 @@ -params['addOns']; - $groupedModifications = &$response->params['groupedModifications']; - $modificationCount = &$response->params['modificationCount']; - - /** @var DevHelper_ControllerHelper_AddOn $helper */ - $helper = $this->getHelper('DevHelper_ControllerHelper_AddOn'); - $modificationCount -= $helper->filterKeepActiveAddOns($groupedModifications, $addOns); - } - - return $response; - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/CodeEventListener.php b/library/DevHelper/XenForo/ControllerAdmin/CodeEventListener.php deleted file mode 100755 index 80d492a..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/CodeEventListener.php +++ /dev/null @@ -1,69 +0,0 @@ -params['addOns']; - $listeners = &$response->params['listeners']; - $totalListeners =& $response->params['totalListeners']; - - /** @var DevHelper_ControllerHelper_AddOn $helper */ - $helper = $this->getHelper('DevHelper_ControllerHelper_AddOn'); - $totalListeners -= $helper->filterKeepActiveAddOns($listeners, $addOns); - } - - return $response; - } - - public function actionSave() - { - $dwInput = $this->_input->filter(array( - 'event_id' => XenForo_Input::STRING, - 'description' => XenForo_Input::STRING, - 'callback_class' => XenForo_Input::STRING, - 'callback_method' => XenForo_Input::STRING, - 'hint' => XenForo_Input::STRING, - 'addon_id' => XenForo_Input::STRING, - )); - - if (!empty($dwInput['event_id']) - && empty($dwInput['description']) - && empty($dwInput['callback_class']) - && empty($dwInput['callback_class']) - && !empty($dwInput['hint']) - && !empty($dwInput['addon_id']) - ) { - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = $this->getModelFromCache('XenForo_Model_AddOn'); - $addOn = $addOnModel->getAddOnById($dwInput['addon_id']); - - /** @var DevHelper_Model_Config $configModel */ - $configModel = $this->getModelFromCache('DevHelper_Model_Config'); - $config = $configModel->loadAddOnConfig($addOn); - - if (strpos($dwInput['event_id'], 'load_class') === 0) { - $classPath = DevHelper_Generator_File::getClassPath($dwInput['hint']); - if (is_file($classPath)) { - $method = DevHelper_Generator_Code_Listener::generateLoadClass($dwInput['hint'], $addOn, $config); - if ($method) { - $clazz = DevHelper_Generator_Code_Listener::getClassName($addOn, $config); - - $this->_request->setParam('description', $dwInput['hint']); - $this->_request->setParam('callback_class', $clazz); - $this->_request->setParam('callback_method', $method); - - XenForo_DataWriter::create('XenForo_DataWriter_CodeEventListener'); - DevHelper_XenForo_DataWriter_CodeEventListener::DevHelper_markAsGeneratedCallback($clazz, $method); - } - } - } - } - - return parent::actionSave(); - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/Home.php b/library/DevHelper/XenForo/ControllerAdmin/Home.php deleted file mode 100644 index 8200103..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/Home.php +++ /dev/null @@ -1,13 +0,0 @@ -getHelper('DevHelper_ControllerHelper_AddOn'); - $helper->selfCheck(); - - return parent::actionIndex(); - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/Permission.php b/library/DevHelper/XenForo/ControllerAdmin/Permission.php deleted file mode 100644 index 11cf1cb..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/Permission.php +++ /dev/null @@ -1,41 +0,0 @@ -params['permissionGroups']; - $permissionsGrouped = &$response->params['permissionsGrouped']; - $permissionsUngrouped = &$response->params['permissionsUngrouped']; - $interfaceGroups = &$response->params['interfaceGroups']; - $totalPermissions = &$response->params['totalPermissions']; - - $removedCount = 0; - - /** @var DevHelper_ControllerHelper_AddOn $helper */ - $helper = $this->getHelper('DevHelper_ControllerHelper_AddOn'); - $helper->filterKeepActiveAddOnsDirect($permissionGroups); - $helper->filterKeepActiveAddOnsDirect($interfaceGroups); - - foreach (array_keys($permissionsGrouped) as $interfaceGroupId) { - if (empty($interfaceGroups[$interfaceGroupId])) { - $removedCount += count($permissionsGrouped[$interfaceGroupId]); - unset($permissionsGrouped[$interfaceGroupId]); - } - } - - foreach ($permissionsGrouped as &$groupPermissions) { - $removedCount += $helper->filterKeepActiveAddOnsDirect($groupPermissions); - } - - $removedCount += $helper->filterKeepActiveAddOnsDirect($permissionsUngrouped); - - $totalPermissions -= $removedCount; - } - - return $response; - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/Phrase.php b/library/DevHelper/XenForo/ControllerAdmin/Phrase.php deleted file mode 100644 index 596fd01..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/Phrase.php +++ /dev/null @@ -1,28 +0,0 @@ -isSuperAdmin() - && $this->_input->filterSingle('language_id', XenForo_Input::UINT) > 0 - ) { - return $this->responseError('Please use non-super admin account to create non-master phrase.'); - } - - return parent::actionAdd(); - } - - public function actionEdit() - { - if (XenForo_Application::debugMode() - && XenForo_Visitor::getInstance()->isSuperAdmin() - && $this->_input->filterSingle('language_id', XenForo_Input::UINT) > 0 - ) { - return $this->responseError('Please use non-super admin account to edit non-master phrase.'); - } - - return parent::actionEdit(); - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/RoutePrefix.php b/library/DevHelper/XenForo/ControllerAdmin/RoutePrefix.php deleted file mode 100644 index 6e743e9..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/RoutePrefix.php +++ /dev/null @@ -1,26 +0,0 @@ -params['publicPrefixes']; - $adminPrefixes = &$response->params['adminPrefixes']; - $totalPrefixes = &$response->params['totalPrefixes']; - - $removedCount = 0; - - /** @var DevHelper_ControllerHelper_AddOn $helper */ - $helper = $this->getHelper('DevHelper_ControllerHelper_AddOn'); - $removedCount += $helper->filterKeepActiveAddOnsDirect($publicPrefixes); - $removedCount += $helper->filterKeepActiveAddOnsDirect($adminPrefixes); - - $totalPrefixes -= $removedCount; - } - - return $response; - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/Template.php b/library/DevHelper/XenForo/ControllerAdmin/Template.php deleted file mode 100644 index 15725d8..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/Template.php +++ /dev/null @@ -1,28 +0,0 @@ -isSuperAdmin() - && $this->_input->filterSingle('style_id', XenForo_Input::UINT) > 0 - ) { - return $this->responseError('Please use non-super admin account to create non-master template.'); - } - - return parent::actionAdd(); - } - - public function actionEdit() - { - if (XenForo_Application::debugMode() - && XenForo_Visitor::getInstance()->isSuperAdmin() - && $this->_input->filterSingle('style_id', XenForo_Input::UINT) > 0 - ) { - return $this->responseError('Please use non-super admin account to edit non-master template.'); - } - - return parent::actionEdit(); - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/TemplateModification.php b/library/DevHelper/XenForo/ControllerAdmin/TemplateModification.php deleted file mode 100644 index 0c2d53a..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/TemplateModification.php +++ /dev/null @@ -1,21 +0,0 @@ -params['addOns']; - $groupedModifications = &$response->params['groupedModifications']; - $modificationCount = &$response->params['modificationCount']; - - /** @var DevHelper_ControllerHelper_AddOn $helper */ - $helper = $this->getHelper('DevHelper_ControllerHelper_AddOn'); - $modificationCount -= $helper->filterKeepActiveAddOns($groupedModifications, $addOns); - } - - return $response; - } -} diff --git a/library/DevHelper/XenForo/ControllerAdmin/Tools.php b/library/DevHelper/XenForo/ControllerAdmin/Tools.php deleted file mode 100644 index aace131..0000000 --- a/library/DevHelper/XenForo/ControllerAdmin/Tools.php +++ /dev/null @@ -1,190 +0,0 @@ -responseNoPermission(); - } - - /** @var XenForo_Model_AddOn $addOnModel */ - $addOnModel = $this->getModelFromCache('XenForo_Model_AddOn'); - - $addOn = $addOnModel->getAddOnById('devHelper'); - $xmlPath = DevHelper_Generator_File::getAddOnXmlPath($addOn); - - $addOnModel->installAddOnXmlFromFile($xmlPath, $addOn['addon_id']); - - return $this->responseRedirect( - XenForo_ControllerResponse_Redirect::SUCCESS, - XenForo_Link::buildAdminLink('index') - ); - } - - public function actionAddOnsServerFile() - { - $q = $this->_input->filterSingle('q', XenForo_Input::STRING); - $matchedPaths = array(); - - /** @var XenForo_Application $app */ - $app = XenForo_Application::getInstance(); - $rootDir = $app->getRootDir(); - $scanPath = ''; - - if (strlen($q) > 0 - && strpos($q, '.') === false - ) { - if (strlen($q) < 7) { - $originalQuery = $q; - $q = 'library/'; - $matchedPaths[] = 'library'; - - if (isset($_SERVER['DEVHELPER_ROUTER_PHP'])) { - $routerPhp = $_SERVER['DEVHELPER_ROUTER_PHP']; - $routerPhpDir = dirname($routerPhp); - $matchedPaths[] = sprintf('%s/addons', $routerPhpDir); - - list(, $addOnPaths) = DevHelper_Router::getLocatePaths(); - foreach ($addOnPaths as $addOnPath) { - if (stripos($addOnPath, $originalQuery) !== false) { - array_unshift($matchedPaths, $addOnPath); - } - } - } - } - - $parts = preg_split('#/#', $q, -1, PREG_SPLIT_NO_EMPTY); - - $prefix = ''; - if (count($parts) > 0) { - $prefix = array_pop($parts); - } - - if (substr($q, 0, 1) === '/') { - $scanPath = '/' . implode('/', $parts); - } else { - $scanPath = rtrim(sprintf('%s/%s', $rootDir, implode('/', $parts)), '/'); - } - - $pathWithPrefix = $scanPath . '/' . $prefix; - if (is_dir($pathWithPrefix)) { - $scanPath = $pathWithPrefix; - $prefix = ''; - } - - if (is_dir($scanPath)) { - $contentPaths = glob(sprintf('%s/*', $scanPath)); - - foreach ($contentPaths as $contentPath) { - if ($prefix !== '' - && substr(basename($contentPath), 0, strlen($prefix)) !== $prefix - ) { - continue; - } - - if (is_dir($contentPath)) { - $matchedPaths[] = $contentPath . '/'; - } else { - $ext = XenForo_Helper_File::getFileExtension($contentPath); - if ($ext === 'xml') { - array_unshift($matchedPaths, $contentPath); - } - } - } - } - - $xmlPath = DevHelper_Helper_File::findXml($matchedPaths); - if (!empty($xmlPath)) { - array_unshift($matchedPaths, $xmlPath); - } - } - - $results = array(); - foreach ($matchedPaths as $matchedPath) { - $relativePath = preg_replace('#^' . preg_quote($app->getRootDir()) . '/#', '', $matchedPath); - $results[$relativePath] = basename($matchedPath); - - if (substr($matchedPath, 0, strlen($scanPath)) === $scanPath) { - $results[$relativePath] = ltrim(substr_replace($matchedPath, '', 0, strlen($scanPath)), '/'); - } - } - - $view = $this->responseView(); - $view->jsonParams = array( - 'results' => $results - ); - return $view; - } - - public function actionCodeEventListenersHint() - { - $q = $this->_input->filterSingle('q', XenForo_Input::STRING); - $classes = array(); - - /** @var XenForo_Application $app */ - $app = XenForo_Application::getInstance(); - $libraryPath = sprintf('%s/library/', $app->getRootDir()); - - if (strlen($q) > 0 - && preg_match('/[A-Z]/', $q) - ) { - $dirPath = ''; - $pattern = ''; - - $classPath = DevHelper_Generator_File::getClassPath($q); - if (is_file($classPath)) { - $classes[] = $q; - } - - $_dirPath = preg_replace('/\.php$/', '', $classPath); - if (is_dir($_dirPath)) { - $dirPath = $_dirPath; - } else { - $_parentDirPath = dirname($_dirPath); - if (is_dir($_parentDirPath)) { - $dirPath = $_parentDirPath; - $pattern = basename($_dirPath); - } - } - - if ($dirPath !== '') { - $files = scandir($dirPath); - - foreach ($files as $file) { - if (substr($file, 0, 1) === '.') { - continue; - } - - if ($pattern !== '' - && strpos($file, $pattern) !== 0 - ) { - continue; - } - - $filePath = sprintf('%s/%s', $dirPath, $file); - - if (is_file($filePath)) { - $contents = file_get_contents($filePath); - if (preg_match('/class\s(?.+?)(\sextends|{)/', $contents, $matches)) { - $classes[] = $matches['class']; - } - } elseif (is_dir($filePath)) { - $classes[] = str_replace('/', '_', str_replace($libraryPath, '', $filePath)); - } - } - } - } - - $results = array(); - foreach ($classes as $class) { - $results[$class] = $class; - } - - $view = $this->responseView(); - $view->jsonParams = array( - 'results' => $results - ); - return $view; - } -} diff --git a/library/DevHelper/XenForo/ControllerHelper/Editor.php b/library/DevHelper/XenForo/ControllerHelper/Editor.php deleted file mode 100644 index 72714a8..0000000 --- a/library/DevHelper/XenForo/ControllerHelper/Editor.php +++ /dev/null @@ -1,26 +0,0 @@ -_DevHelper_disableAssertPostOnly = true; - - $limit = $this->_input->filterSingle('limit', XenForo_Input::UINT, array('default' => 10)); - for ($i = 0; $i < $limit; $i++) { - $this->_request->setParam('title', sprintf( - 'Thread Title %d-%d', - XenForo_Application::$time, - $i - )); - $this->_request->setParam('message', sprintf( - 'Thread Body %d-%d', - XenForo_Application::$time, - $i - )); - - try { - $response = $this->actionAddThread(); - } catch (Exception $e) { - return $this->responseError($e->getMessage()); - } - } - - return $response; - } - - protected function _assertPostOnly() - { - if ($this->_DevHelper_disableAssertPostOnly) { - return; - } - - parent::_assertPostOnly(); - } -} diff --git a/library/DevHelper/XenForo/ControllerPublic/Thread.php b/library/DevHelper/XenForo/ControllerPublic/Thread.php deleted file mode 100644 index 71c41db..0000000 --- a/library/DevHelper/XenForo/ControllerPublic/Thread.php +++ /dev/null @@ -1,38 +0,0 @@ -_DevHelper_disableAssertPostOnly = true; - - $limit = $this->_input->filterSingle('limit', XenForo_Input::UINT, array('default' => 10)); - for ($i = 0; $i < $limit; $i++) { - $this->_request->setParam('message', sprintf( - 'Post Body %d-%d', - XenForo_Application::$time, - $i - )); - - try { - $response = $this->actionAddReply(); - } catch (Exception $e) { - return $this->responseError($e->getMessage()); - } - } - - return $response; - } - - protected function _assertPostOnly() - { - if ($this->_DevHelper_disableAssertPostOnly) { - return; - } - - parent::_assertPostOnly(); - } -} diff --git a/library/DevHelper/XenForo/DataWriter/AddOn.php b/library/DevHelper/XenForo/DataWriter/AddOn.php deleted file mode 100644 index 397c955..0000000 --- a/library/DevHelper/XenForo/DataWriter/AddOn.php +++ /dev/null @@ -1,15 +0,0 @@ -DevHelper_actionSave($this); - } - - parent::_preSave(); - } -} diff --git a/library/DevHelper/XenForo/DataWriter/CodeEventListener.php b/library/DevHelper/XenForo/DataWriter/CodeEventListener.php deleted file mode 100644 index ef74056..0000000 --- a/library/DevHelper/XenForo/DataWriter/CodeEventListener.php +++ /dev/null @@ -1,29 +0,0 @@ -get('callback_class') - && $callback[1] === $this->get('callback_method') - ) { - // triggering error for our generated method - // this may happen if we modified an existing listener which had already been loaded to memory - // ignore it... - return; - } - } - } - - parent::error($error, $errorKey, $specificError); - } - - public static function DevHelper_markAsGeneratedCallback($clazz, $method) - { - self::$_DevHelper_generatedCallbacks[] = array($clazz, $method); - } -} diff --git a/library/DevHelper/XenForo/DataWriter/Template.php b/library/DevHelper/XenForo/DataWriter/Template.php deleted file mode 100644 index 7690b2c..0000000 --- a/library/DevHelper/XenForo/DataWriter/Template.php +++ /dev/null @@ -1,24 +0,0 @@ -getMergedData(); - $filePath = DevHelper_Helper_Template::getTemplateFilePath($template); - XenForo_Helper_File::createDirectory(dirname($filePath)); - - return file_put_contents($filePath, $template['template']) > 0; - } - - protected function _postSaveAfterTransaction() - { - $this->DevHelper_saveTemplate(); - - parent::_postSaveAfterTransaction(); - } -} diff --git a/library/DevHelper/XenForo/Debug.php b/library/DevHelper/XenForo/Debug.php deleted file mode 100644 index f7c0b81..0000000 --- a/library/DevHelper/XenForo/Debug.php +++ /dev/null @@ -1,52 +0,0 @@ -getRootDir() . '/library/XenForo/Debug.php'); -$contents = substr($originalContents, strpos($originalContents, ' $oneData) { - $rows[] = sprintf( - '%s%d%.6f', - $label, - $oneData['count'], - $oneData['elapsed'] - ); - } - - return sprintf('%s
', implode('', $rows)); - } -} - -eval('abstract class XenForo_Debug extends DevHelper_XenForo_Debug {}'); - -if (false) { - class _XenForo_Debug extends XenForo_Debug - { - } -} diff --git a/library/DevHelper/XenForo/Model/AddOn.php b/library/DevHelper/XenForo/Model/AddOn.php deleted file mode 100755 index e41113e..0000000 --- a/library/DevHelper/XenForo/Model/AddOn.php +++ /dev/null @@ -1,34 +0,0 @@ - $groupAddOnNames) { - $options[$groupId] = array(); - - foreach ($groupAddOnNames as $key => $addOnName) { - $options[$groupId][$key] = $addOnName; - } - } - } - - return $options; - } -} diff --git a/library/DevHelper/XenForo/Route/PrefixAdmin/Templates.php b/library/DevHelper/XenForo/Route/PrefixAdmin/Templates.php deleted file mode 100644 index af88dac..0000000 --- a/library/DevHelper/XenForo/Route/PrefixAdmin/Templates.php +++ /dev/null @@ -1,22 +0,0 @@ -getAction(); - if (strpos($action, '_') !== false && intval($request->getParam('template_id')) === 0) { - /** @var XenForo_Model_Template $templateModel */ - $templateModel = XenForo_Model::create('XenForo_Model_Template'); - $templateIds = $templateModel->getTemplateIdInStylesByTitle($action); - if (!empty($templateIds[0])) { - $request->setParam('template_id', $templateIds[0]); - $routeMatch->setAction('edit'); - } - } - - return $routeMatch; - } -} diff --git a/library/DevHelper/XenForo/Template/Abstract.php b/library/DevHelper/XenForo/Template/Abstract.php deleted file mode 100644 index 41bbb80..0000000 --- a/library/DevHelper/XenForo/Template/Abstract.php +++ /dev/null @@ -1,31 +0,0 @@ -getRootDir() . '/library/XenForo/Template/Abstract.php'); -$contents = substr($originalContents, strpos($originalContents, '_params['addOn']) && empty($this->_params['serverFile'])) { - $addOn = $this->_params['addOn']; - $this->_params['serverFile'] = DevHelper_Generator_File::getAddOnXmlPath($addOn); - } - - parent::prepareParams(); - } -} - -if (false) { - class XFCP_DevHelper_XenForo_ViewAdmin_AddOn_Upgrade extends XenForo_ViewAdmin_Base - { - } -} diff --git a/library/DevHelper/XenForo/ViewRenderer/Json.php b/library/DevHelper/XenForo/ViewRenderer/Json.php deleted file mode 100644 index d174c54..0000000 --- a/library/DevHelper/XenForo/ViewRenderer/Json.php +++ /dev/null @@ -1,71 +0,0 @@ -getRootDir() . '/library/XenForo/ViewRenderer/Json.php'); -$contents = substr($originalContents, strpos($originalContents, 'getProfiler(); - $params['_queryCount'] = $profiler->getTotalNumQueries(); - $params['_totalQueryRunTime'] = 0; - - if ($params['_queryCount']) { - $params['_queries'] = array(); - - $queries = $profiler->getQueryProfiles(); - - /** @var Zend_Db_Profiler_Query $query */ - foreach ($queries AS $query) { - $queryText = $query->getQuery(); - $queryText = preg_replace('#\s+#', ' ', $queryText); - $queryText = trim($queryText); - - foreach ($query->getQueryParams() AS $param) { - $param = sprintf('{%s}', htmlentities($param)); - $pos = strpos($queryText, '?'); - if ($pos !== false) { - $queryText = substr_replace($queryText, $param, $pos, 1); - } - } - - $params['_queries'][] = htmlentities($queryText); - $params['_totalQueryRunTime'] += $query->getElapsedSecs(); - } - } - } - - return $params; - } -} - -eval('class XenForo_ViewRenderer_Json extends DevHelper_XenForo_ViewRenderer_Json {}'); - -if (false) { - class _XenForo_ViewRenderer_Json extends XenForo_ViewRenderer_Json - { - } -} diff --git a/library/DevHelper/addon-devHelper.xml b/library/DevHelper/addon-devHelper.xml deleted file mode 100644 index da21956..0000000 --- a/library/DevHelper/addon-devHelper.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - ]]> - {xen:phrase devhelper_data_manager} -{xen:phrase devhelper_file_export} - -$0]]> - - - - - - - ]]> - {xen:phrase devhelper_data_manager} -{xen:phrase devhelper_file_export} -{xen:phrase devhelper_switch_context} - -$0]]> - - - - - - - ]]> - ]]> - - - ]]> - ]]> - - - - - - - #]]> - $0]]> - - - ]]> - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/xenforo/.gitkeep b/xenforo/.gitkeep new file mode 100644 index 0000000..e69de29 From 877cb192f46a8bc11595c44f2e228c616e4f8a0e Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Thu, 26 Oct 2017 23:29:46 +0700 Subject: [PATCH 013/118] Add support for `full` add-on files structure --- dev-scripts/docker/find-addons2.sh | 2 +- src/addons/DevHelper/Router.php | 12 ++++++++++++ src/addons/DevHelper/XF/AddOn/AddOn.php | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/dev-scripts/docker/find-addons2.sh b/dev-scripts/docker/find-addons2.sh index b28adb9..9e5e7d1 100644 --- a/dev-scripts/docker/find-addons2.sh +++ b/dev-scripts/docker/find-addons2.sh @@ -6,5 +6,5 @@ cd /var/www/html/ { \ echo "# Generated by $0"; \ - find addons/ -maxdepth 5 -name .git -type d | sed 's#/.git##'; \ + find addons/ -maxdepth 5 -name addon.json -type f | sed 's#/addon.json##'; \ } > ./xenforo/internal_data/addons2.txt diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php index c8ede29..0ae8867 100644 --- a/src/addons/DevHelper/Router.php +++ b/src/addons/DevHelper/Router.php @@ -132,6 +132,18 @@ public static function locate($fullPath, &$success = null) $candidatePaths[] = $parentPath; } } + } else { + // for non-PHP files, we support 2 types of add-on files structure + $fullSuffix = '/src/addons/' . $addOnPathSuffix; + if (substr($addOnPath, -strlen($fullSuffix)) === $fullSuffix) { + // `full` type has js files in addons/AddOnId/js/ + // and `addon.json` is at addons/AddOnId/src/addons/AddOnId/addon.json + $candidatePaths[] = substr($addOnPath, 0, -strlen($fullSuffix)) . $shortened; + } else { + // `repo` type has js files in addons/AddOnId/_files/js/ + // and `addon.json` is at addons/AddOnId/addon.json + $candidatePaths[] = $addOnPath . '/_files' . $shortened; + } } foreach ($candidatePaths as $candidatePath) { diff --git a/src/addons/DevHelper/XF/AddOn/AddOn.php b/src/addons/DevHelper/XF/AddOn/AddOn.php index 97af710..6631d77 100644 --- a/src/addons/DevHelper/XF/AddOn/AddOn.php +++ b/src/addons/DevHelper/XF/AddOn/AddOn.php @@ -15,6 +15,11 @@ public function __construct($addOnOrId) /** @noinspection PhpUndefinedFieldInspection */ $this->releasesDir = '/var/www/html/xenforo/internal_data/releases/' . $addOnId; } + + public function passesHealthCheck(&$missing = [], &$inconsistent = []) + { + return; + } } if (false) { From 942f4117a2bd1f528b1f0b4847d76a7e1bea2351 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 1 Nov 2017 11:18:32 +0700 Subject: [PATCH 014/118] Add support for self-signed https --- dev-scripts/Dockerfile.php-apache | 9 ++++++-- dev-scripts/docker/ssl-cert-snakeoil.key | 28 ++++++++++++++++++++++++ dev-scripts/docker/ssl-cert-snakeoil.pem | 17 ++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 dev-scripts/docker/ssl-cert-snakeoil.key create mode 100644 dev-scripts/docker/ssl-cert-snakeoil.pem diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index b7fb859..85b8a31 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -11,7 +11,12 @@ RUN pecl install apcu \ && docker-php-ext-enable apcu COPY docker/* /usr/local/bin/ -RUN chmod +x /usr/local/bin/cmd.sh \ - && chmod +x /usr/local/bin/find-addons2.sh +RUN chmod +x /usr/local/bin/*.sh + +RUN mv /usr/local/bin/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key \ + && chmod 0640 /etc/ssl/private/ssl-cert-snakeoil.key \ + && mv /usr/local/bin/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem \ + && chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem \ + && a2enmod ssl && a2ensite default-ssl CMD ["/usr/local/bin/cmd.sh"] diff --git a/dev-scripts/docker/ssl-cert-snakeoil.key b/dev-scripts/docker/ssl-cert-snakeoil.key new file mode 100644 index 0000000..d64eda6 --- /dev/null +++ b/dev-scripts/docker/ssl-cert-snakeoil.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCuLUoflUrEZWbb +2E4vEItF51ho9jjYSaXd7q0Q5yuQvw0vF3a5Ucm9bIWkxJMKBvznWRut+1yKB8kM +Yi9z+vHpw+A814Mr91WVcwEaH4VdpPAY6iyH3/wfu61poeVifnN5yH02Z/CkC6c0 +/UR9yrE9nGLZ883LTMhPYo/8YoAgFdzZ82aMoMf7ZH8WU3YyWMrvc98hQxsbqcMu +djXv1301FY9U/S9ybUaJnoRCWOgLGP4IU9rWOfOEs9PtJpax55i3WDTjEPIlvfFq +bpQAUQDx8+9ZpSpma1iRLx8vytZdTiLxOORIeoYpqWINxNoj6MIGetMMKSKCn1Lu +kTWqs1qhAgMBAAECggEAOUB9yt/h0aibJMx29pVzkii3MNkuWjnrIYYgsRurgEqs +ZLxLtCKkM3WGgGB1DKi7XLg3lvq2slBYz48+ldr4xaQzAwy7+ymzogpJZHLT/bIH +kcj3ljoTv8KK/9vNcJCsGG3EaqvDt8h0z8AoUUjc9al//LBdBuRYO2/kcEtYXjMG +UOOJdX1n/HDsS3gLnC+TN2m1NFXdt9//AO4lCdbkdAPhc90h44nKOSXl4nZZe3uw +GNUSmKkY57YZd84Ybyca2DX6hkpBWNSIBbMyU2c2k1Ka5RjVhEVYgyNiCvGsA8Fa +gGat1KJerS9wOcBRub6qY8mMxtFztgSST8uZGRbcIQKBgQDjTw254uXeK0Xt3Ml3 +Vs7IZUdJK6fP1NFN8lsFCchsZ9aUD+S4zw5o0WBsF8TS399SeczrmhVy3MiLEd4C +SDTVCMikj2A+VTs7v1ZpqyADh+9xybFq1NOx2dnyB6ochFVAeeEAqE+Pcy6cVmow +p4/P/9R+tiGshn2mQXPzfzVUBQKBgQDEKWePUlm12+W05SkI9L4LTFgGhZnwTDhr +t35ZeFM0Ih2qcIkf2t8eVRtVgYqBSg/F4o4efOmoyif5C96Y9h9PicJGYglcDUkc +XXSGkUHjjHdnZAhxSgSjyXf1QGvwVFtfy5XNAdOB5pVsN6UPhNoAYE0xzCapTiZg +ZuHgZ+jq7QKBgE/iYHiLfS1vF8xYY5VFNLbIoRzd8sPfjw9NtR84KO+wLoEqdL9e +RTohGznhwJI7i0h49cN3C0KqxO/a/6LdrXOQ+rKakMBXQ9HjlILeWQnkpAnhUDCz +SxKd9TJR7z7GYw+dxa1teUh4ulDHLdqbiLcYuZ0udPck7NOY/R79/cfhAoGACnkX +cVx5M69w3S6a+UJv3xSNYpPBe0XmgUHDui0lbBQiN1ZYy92YqfrrQa5v4aU9oFgP +NGuA4iUg6zgKA2qok0uMlstnKoX/EEehEAozVV3LhjaeCMZl5wS7pdlxqdwnIL8y +2UYur7HK6oMyCdkS9pAtrunyanmkrOLxTlTd56UCgYA4qSWFyCj4HhMc/IVUfQO3 +qsqu+2gsNJefR+Wk9iwoNFPWcHHX8SEBT6fa+Yl18OVTbaEtB2Oit+69Snu8/dKA +icsNheL/djmy2iAd4fDdNmgcZtg5t1Aiu4GmDMZzcydz1O255wxx0Qo+Sb2/ReV9 +Wsdg1FBo2W4107vFpQokNw== +-----END PRIVATE KEY----- diff --git a/dev-scripts/docker/ssl-cert-snakeoil.pem b/dev-scripts/docker/ssl-cert-snakeoil.pem new file mode 100644 index 0000000..c05f2e6 --- /dev/null +++ b/dev-scripts/docker/ssl-cert-snakeoil.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvjCCAaagAwIBAgIJAL2kworg9DfqMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV +BAMMDGFmMjUzYjViOWFmODAeFw0xNzEwMzAwMzU2MTRaFw0yNzEwMjgwMzU2MTRa +MBcxFTATBgNVBAMMDGFmMjUzYjViOWFmODCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAK4tSh+VSsRlZtvYTi8Qi0XnWGj2ONhJpd3urRDnK5C/DS8XdrlR +yb1shaTEkwoG/OdZG637XIoHyQxiL3P68enD4DzXgyv3VZVzARofhV2k8BjqLIff +/B+7rWmh5WJ+c3nIfTZn8KQLpzT9RH3KsT2cYtnzzctMyE9ij/xigCAV3NnzZoyg +x/tkfxZTdjJYyu9z3yFDGxupwy52Ne/XfTUVj1T9L3JtRomehEJY6AsY/ghT2tY5 +84Sz0+0mlrHnmLdYNOMQ8iW98WpulABRAPHz71mlKmZrWJEvHy/K1l1OIvE45Eh6 +himpYg3E2iPowgZ60wwpIoKfUu6RNaqzWqECAwEAAaMNMAswCQYDVR0TBAIwADAN +BgkqhkiG9w0BAQsFAAOCAQEAVPMo4zeyMy3Sky+pmrxAc6ORIRpG0eKDw+8Uo+Vn +nrzJ/wChyJbJ3tpIX2CWn3BvA2T/DHuCr4FTcBQHWWo6alhWagAnQ5i+RMVPP+8A +6ZES46lhRX3jxngkQ4iuQCeOtT/1qpvHmp4U1jZ3mGoopEvbMd7kn1ByS7DxsFxQ +RMEw1JvjSESzncnQJ0CoyxCqMd5UE749jcitvHNEhI5SU4smjdwy60NHP2xgBfxf +YebDtYQkIrp/6usr+1E+wGw1WkoJyoBrIlX7Mfgzv2R3UEiMJ3oEqu1F6tgs6AQo +Qg+2fXkrqtySheVEg0ebKTambjbzWxv5VCUo74q56rDKMw== +-----END CERTIFICATE----- From fb18ad4cdecdef547a3c1131cfbf782c4e93abde Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 1 Nov 2017 11:18:40 +0700 Subject: [PATCH 015/118] Add support for composer.phar --- dev-scripts/docker/composer.phar | Bin 0 -> 1852323 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 dev-scripts/docker/composer.phar diff --git a/dev-scripts/docker/composer.phar b/dev-scripts/docker/composer.phar new file mode 100755 index 0000000000000000000000000000000000000000..508f9cf274be7a7526630f9ef01c183e6b17612f GIT binary patch literal 1852323 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 z

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≧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ⅈ+uu6?hhryz`hx1-6E8^hu#QTte?Cf6ZN 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�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%0D}p%Hh{e#zU+^n?Yl_1L0!#ZC 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›xQX zi%cabBjy~TbFL=d|G_y0BjcG582Pjh+{t!RqArA-qc)Vj;fPj;%3v{W^g^lP-{kH{ zA7?C=kST@bk}Kl3$zS98Jw6`wvt0#}4U>dT-S9X@S%7t1Cuw&MNZCzv*wzPb{bq_% zXll|U(I2BF+Y-U>QGZ-#GN<=e<#hEM7jEj~ z^2VO1i;v;{IY1#w5J_2l+a9EJ@~A%o0jfOxH~ZRYw>nK41^=Z^`V83DWExVA25hQ!zbxFurf{O%cXknp0 zgEQ&`cLstCPup!I=RmSObNZxPt=3j+<>Q^L>dtCyJ=MG+n|H_K{tsv&=WxgoqVdhG z*DBk`>rYoJNkG9Kqd~u0@Cj@R;vbnU;3kn_=LB{;qGtNog%cZI$S~)B|F&h z@ZsIuzd}bilJs?bRA27aR$nB0;n)kqPslHNCB~iWG~mPB(#dL7tsz53(chCZZ!A%qf^>O^U*or}JyN}WDH3zqbDoQ`GNbfOuVN)#XvPlnS%wOvAvv%^qh zp}^YkPCUyOA&e^9Xl1>d7T}Lcr!A$<%p^w=5Ue%Ed`#T4;{LI1u0f9 zx>f!bZ=JjWfnE+_`g_Qx5a!lxb7RilcZTKjixG%ROnzepH0a)6^e@<)ISsTOXfC?5 zEtLeCW9>&ljGR6dAlJ5zv_)#6h>v$X~1rg=vEHji221IIg&N7EFdCmwDrdHPpl>K}` zVeAzlwu28c8m6}JxPUH`*_HGKw#WHJhhQ2+p2Y=8tAf7r=5%>^`3Jx%&b|V!MlQd= z%=7wSxt4ei|1SNm|GugfUjMfEyF6Km{+%hwjovelONU=dukOvgmUlBNxbT>jXK+C< z^dR>!=Ee++I;RDXM7`{S{ABhth%Zh+cPC2Pr}1h6>nwBkjrx}tI9vh;omK(u>CV(J z#;k7W0$P=pT{*cdjR^!iM<(0q*LWB}Eh*nQObQ@{R~-$HlF6ns zC;im@e#4`K*C~#f*0)SyI@*(CQSN7^9CX5?NG}}!UbiBsfGJC=z3*}@M@nu&AV%9Y*K?c@E*USn$m!IhS~w_e#Ii2`-)L9f|GvUUi(4;|Qvmav`7iAT0+G=0e} z9}iXfg*!eOJ=dL+gbzET0>!q^l;FjB@B=9%ItIj~lvypSou-S1jVhFs$VOXR;t`;s zWW#orF@{0bO4V_ss&80p+RwP6J~A<#qwzsLCp&LI?ZB)^YOE^n0;6M!bAuh?s@zaU;7M*Nh&pXk&JA8N)VP2ixLUUi@v zhQyqB?>0jIvD4YYNh~Mhiy*bRLHkV`!N{j=@L-70yIsf2{*HyO?AUi_Xc1U{D`Lm= zP4V}M5K~Dpz0wInQWlnkq;&Lz6$ezQR^;n3qH5Hy=w@?Ou;(TsGhL~2SQ`acp<57> zssYf*lg%Mnp$$q2jQhjx)=GssaveB*J`xBdU}3fiEo12fZG*VScMc5kW=VJ-aX3GM zLA5qx93|G_E40S2QJbQ1Ob$Vz7$cKAroN*}d9(+Lmw-<>(>hR0=%a+FNNAwRIs()< zPz*)b!sW@4H)6C!gEaC;AezOn1VMao<4RTj1ZE`jf7nVI2M0TS`>9w?wFG+p^Z^`_tDi2VK7fk--(nD8hnm46XHBpMZrl z0%AML@%bI+L~-hD5x%r8(rR^ZY?V?S_qCi2`X5CxOK(S%il_C;HdZ*C)`p3VKw|74 z&bZwBdsjiP#R;EA65w`30uzUm$+$6rncj=x1-gc8ot*a#$0WPP0m0 zp{M25jdI2E!c8bwDc9 zX4kG%)Llr?hh>&zZL)|IQzG89v6sA~8^xp>%3bT5il}T-NST;-;xal9ICC?^>3SJU z%34hjr5USfpZWwSgu?wz;dk$s9gMaXR$n=K}YJ3$p8E|UQNBvVN zkhkKmQ&?jEg=2=ogb@QCPS!%GFk>%^0^mzGf&ufzxk z@gRHQMxa2E`T)W9$MWJB*GIOx@Zb8WL+Z}Kpw|Z-;4c=MnF2?P^o?;tG6V4gQihht z%0}98^n@2wu8*l;*kr-EsuBogu>ILiLBeSxg=9Jmj9eLq=2Rt7;BF)u# zY8?q!K|l_phR>qNV|_@T3na>j<*uuL(vMsy5-0Em7U>a56hXFADR3XzMiRp7+ab*7 zX9u!bc5T^>nx?-6*Yc<&J3edU-kE`|XE3J5iM8BXvYwfFpq{Ec)^)yV$DvtZoi?7c z3zQKzvb+?g749LI$*>1z55;`5fdSDneR+VX4=$@a!7R`02xrDWX*dQ$QxXun?K zs2m7NM|v~nCOzF=hU!4Qa3^VbP*XB9!0hJ4tEyk6!ufUG$w0+`x!m^$h?)|!ew7(i zCyGLqc((SLTPCQ*X;B!fYeo-4S<0C^Ik|3l5c5*;nph)|qM~HAYs*#s!8btb4@yoBJ(yL!r?mzz9>w7aR z*e||+AHVtYyBYj?^{ad<9r3F@`y2Jcna5uc8P68I@BrK(@N+2G5>OV!Ly&+ULb0=G z5LF~aSI8-kizdj9ZHc)zrETdo@07S4o%IJuK^nh#z&G?Z#Sb68*6e`n_n+7F`>Ocw z%l6{I|)_cNa9*TzBxnqT*=e|`_OUMU}NT2t-0 zH)vPY7Ql4^mwBb#l?(3J9`D3hv$owy9N!r_Ch{!wEFM*uCRuwj9f$X6goQVPcE>G> zZ_f>>1_6jOFGbWD4WyN&YsWW;MsBo1BnYd;?>xqO+#~EF^pVAA%m>UFauUz-NsM(l z03pP<37nBL?LN}L5)I0@{d`p0vK7Mp{ltkhUjQ({f#uC;i23^n{h2?S7dwCc{>*nX z--!T^p#UOOG=t2Lk8~SnO1t$7qQJIwR6H)co+;d4hWmF>sUj}>2rd|gpq4x&4%C!t z0?wr60)8F%)zNSN+^zQ*!^+eX#?%EyOmO1|+d%#E0tsJ!s*57bMLd^ED;YpA9+gpc zBZXrq2dJ21bJ3vCj^lVislSypLMjmJP+H`=7^9VQVbq;GMkfT zP3S4Iyl^zkFBoVF-csrDPj`;yX9QYKzrZS$#*Xp+eJLo1vaF;VO$y4iJobl(A>`B} zIbOiANI+9oe9BzjREI=EW3@61Hm{1tpFLHRQP4bbiY}cwqcWj9$vZddKT`+15c%_u zQeL3ziVG*HcW2;L!MsWp7eVAp(blERzgZLB8UlXh6Dg?Hf2^U7ZCKURVCha{*P=Hh z5BGaJP0AbL&k}s(kX!T}3?IWM!fiW?j+*Ze-rjEwnr}vPrG;0^4_?o>cnfHya)|Q+ z;kG!UgK9{pIkLBL6LVU9dU2lZN(xtwDS`?l=`jYF)accLJ8m>{Z@md>@?evW-6zcw zFb8oH&AF#LQAd0)kQ?aKSjF$CpkY4trDR`wJ>GFahq^jj#86~(iqxHg6dhd-dLmGy zq))vV6?F%1{WRwoy^t7^whgz&W3mLF*v<%RmhU0qyTWBXOUvrM8WXQ0%9sPwM`TAX z`fJ$MuN*}|tzKe*ePeg!4Mg3fVR0KFQY+H42KzAP5ZU5NAY65pc#>2ZGTS^=ov}D6 z9!HqBK%n#Fl+L)p1b{|`8NY$7rxrd_l6`KKa}iP_KB=?L8>kt! zByl?2su7jeX^0+RWKd?p#o~I{+b?d`iDDw|Gg)bYODB(_OZTBt3* zyd|!~uVh&uE*n2Fc3mk=6*pas%v}j=&SIBA&v%0phc+WFfa&S2=b$&ssxJeHVif{_ zg3;h%x)Cq{V^nYu1*{4vi0nWlkH#Am#(ipLn{$_5-pq%MoVW)^VXOZTB*v zG6bH8CeP*ybtfw&ag~570K^~1n#u%w)T)vUN$x}k-N(`KYk1Oh=g!sRC4sudr-z(^ zP+@w4fF-LG)B*3A@S9JdE9GCP^cNm}x1YagJ8*I9l0ZXNcLmVXe!wcr(i4gs$pHMf2wYMn-+ZUd~cC?mT#qrM}$bhEBX z*b58$|B4V-!h8`t0U;hoWQJnz*dM1z$3!GtYXLq0iT8#+`JOHdpGNRb(6{DxU0v|U z--onE2JL2-WL!Ev-q@-fA5(L`KR>Vkhtcgj@-u40coQ!fNDQA2kDo~_ZA4XmiBmU? z6ilPh^r$gxOXOd_eVPkG+Kn|4hDln!Ou&tRNO=m^Z+@sTE*idPJa55+Xif~2jWZQx zDyZIUfz660nFV#Xc|V2^iC7aU;?80MWv3iNArmYKLQHsXL(%XTdAn(!1%T(eN`e z;)AA4Zbw%L>yXf!S$Yujr|)+(9gtg6{2?^;GMW!hJq5nLZj(ugT3-)NRoVzH9d@|E zsKq>!TRwsHs54us;yj$|GVS!TP&-CQrvvQ{mKp($!bPQ!uLn73^+E;TZ>lWpf-2Xw zrjbr*X6{iqKa_a2vNGxLAViBFpo@_GZv-7jT;ylT*Fr&EtI}@cmT4c~HnEIEO|! zWRA0WxD@IXouDK3`sTZkmvFRcFlX$JumtwO7Rifg5j2Zv5-2{RoQN+Y=F z?^dnGT}&T3XBknw6g*jy#vrLZFy<~Q>f_vTVoOi4TR+o_v z(I~f`W(CgK!Z{L}y}<=dl4Kicu&7B55q8f#i9zS&a)grbly^I)ZG^AG0pDxg2cJRs zAW>KU0*5}QfRz|JDMQeK8}x4|V!wrtXV@5x%gU)Kxc$*3kiy~ir-lgNMUU^0=8I2Q z{7s*CuyJS*%PmO?G+ddQs^L}hr2nBUW6_C4@E1T8bjt(?5J(>eEZeK$8BQxOiL4?F z{ldA3M-cfO4ilNl)&M5H1KeNq2gEO)Cx>0Z57Kna{RsJ$%gZ5CE{UlxAZ+TEBflwa&u%GGLNuQIi@v%kGn#V29S!RvGm+3p?cs5~(2x+1l3jR_*2N)aF)gmu+tD zRSK(x{nbisYn|L**soXi_o`)dzkz0Vw{|xx=%vh6a2~zlS)ts(k3#h+*G_abwOR-C z6~b3o-`js#*?RJ{R(QI%jUyJ-!de-St*&jCwJQv2eS39lXST4hy0iL(&{Yb1Xr(g6 zVhUa1;AxqU*xxGtzb*?ehOxfK!x-zeS&Xt$^HmSFs^!_jYGtcRglty!c4nuDPSil_ zXax0k%i0Q2EeP^6f+9p%9fNkT6gJ9O@OPhJdUj=quJC+H9gM^2orpN9UbL>Lg~-_@ z{@7No7*YoWWkRFb-dZp3R?F4n%`IRC+RPBe=8SuWx{-$_oO`<)9!Kk3MPOMzZS6SanaCKs*Ug>(Mno=$Dyi`;X@~+!;b9Q z=<>kFUfIM7<%}Q?Sh{&EPS(uYr!8E9H|o6UFl7t!P}p~NN^J$naj=HE^VbdoJap_z z#;#52*x@N?4Y}2zCfIYyXe`$E5Zkt#TG{4xwKOgwbVz$>{%myK{hO7jA)^=dShup- zc=mtp1p^88ZYoB&`Y*sD-Br&ATWj8w#H6Kk5&1HLs zL^Ms>&7$>2&ot%CX zpycKYTbn*#gKh2y*ZkN7zop`;#OY%pr*6}G8#dqP^<oM{jqH}};X#tA-FnIHoZR^Zyi=mDaO-5ho*e>)@u^6J^MrRP8tZj9WHVAxaz99`9 z174W2BrH{lT`PkD>w?L2nw;w9Op>S25uE~}>j9?|m0UXq}RcZ&0})qX{eTFem`m&P*sO zgEJcUNuG|+k+;7ne#w7d;siIiNEsaIM*QtUt`ZGaSXYCoL*iLX#L2V>!7sN`@a3sV|zljV&u{uo`(W;j;lLL`=-SHi5!JcfqTs0pRZUhxj2 zp_a-+p>Nw)X!)m~ev%A=0JQYDgo|jmcFQwU1$_Qi=(KcQSt%@jS1PP-?>}8F+%Ifw zJ=v<^?;QS{FKAf=xw^uSUL9R*A6@Lu&ml|V?C&#(Kaj?3taF{#N@3J|k38Mt#Kr>w1!Y zkpdm9Ji@8&xS7)9e}rac9!KrOZ#?0^FLdlc(H4*d z!P!cH=pR-K=`@b+JuZAHBpxMxqoo-S4R*UOm_FOVBj5lrHm8L`5?p#E?oW6pHmw_g zpA8w8ua(oK*!X$RLtlAsq1EI(wvG@_Unu3hFU$m*cGcz7?IWp4Vg~XuNJiq8!qM;^ z-mTDG^@T&7u_q4ue#DrDna934Hu;YgXyvs_NW1d#qckDLNP zr0z2i;r03g$H|xe;LBdcgXzmh9UGjUBEsxB@}hKDEaebF9(FzK)=r8{^B_>_%px3q zXUHgAB~MS59$cN8`nAM+2T)~qZ?#%2!&`)%keJ+~4v~>{>i4TD5q}hka?}DMQI>Q0 z!6-3^$w)OuIqJO&s>MkmE_$}=hLgoC6eYp%1tY~cn}VbwGWm_a1C-c+Hh6z<2?ZEZ z8+xX7iTIQojR z>M&;MrreqU-O+u<+0_WGfWxDP6erko!yXef1ztsGUzcbgn`l#OmZA^aOmX4jBl;+O zjaVsn?xKu2AG+Nel>dF%?AH2mlcBX6_5bs&0qDY8{cVH(>8tzv14jJQ?MK}HRxJN~ z`#!M|_RW)fXF|8*$Sa3Pr;pcRWx3JRB1E?_r49~Yh`Lasv4Ijg7K7LHEL;QPO+we&w+V%rimqpw}q$%fgC>=PG z*UIs|g4#c`7JW5YgIwIw<(W~;ZM}{uXFh=%+uGdQKQ2E9PH;QRsqBp6!FCM~d~6jT zaElZHRKCO$mROD-u*8Gt0gRQO3lBZ1nRm$+GCd)(cL91tDe@k-cr{|0SoCk z!2UdhnSA(D^4WF`1tHQC1-Hw1_$c}82@5_-6@0>iKc!0IinpmEL}#K&J~ZwOj`7rp zz<*&x5!7;$l(KBfKO~lMM<^D;=ozraXNiJDHXcGv2nC;LK@28(NSvb}MZN+W2>>UG zIU~_ylSHYfF>(7TOvUd0fzl$$9Dm6QIbrL3qgh$O`pw|_I{@ESH6yVg(HW-xJ%poN!+QT6)89>E=Uq7 z*+QH3+iJLwo}phZakDEsJLR_@upfz-rFQqt$_m7L9;V=YQ8bt!ca4ClCk+XnYL)E9 zPbltmaJRlFRx@a|3Tkw~E@(o*I>CRgV|+DrYz-l9i0c;Cq1S^7r2`$>LThRIMIw3ZR(M;(rm)?+{X-=X2+zI3`=~_)FxBTbgwVA#hxW) z3FnxxdPp*lB)wx{a~I+{TrnxTSLJrUqPd{%#Z694XkF^ox$RUt#SSPCcituD*Q1Vc7*v4Bi}pSUcNxuOoPft)IVPeHEy zr0Zs^xcp*iCF?8w3jjb3F}ZLt!27>ws~d%Qipjyz{~aqjJOA;-2486L)oTfF`f57% z6TO4$Iy+xG(Wl;bCMjkiP~2S!X#*^Jg-Y)(dpJw*p>3vFn&x9oUG#mbkj^n+nQ2`U zP_;-Jk*_2wN-Z|}i3Lz4K?H&oam_hpHw_Zla6Nz!ho6Ne%_Z;8vZveV4AF$^D8C8! zb{rTT1iuYkp}2`V0Sx!rwUMQ%TUov$n&U+!LLNnYIv^FV9U>$mHT-62YM{}SM1C^2 z8pUUd9n**X)v!?9zTZ1H@7Q+}dUmjYb238u|3?BS!l4hgW8l*5rXy}eV%>c}YxG74 z*u;PFRU8OTMJAGr`zwn=>{DHwREq?;#RBckTTvK zDM#ft%JOgyPeD#8=c1`?`^+`PEkO4%fs)=#8{%x&5T_Lo*BDgfc=!N^eCLB)O?66i zL*~qT4#>Hq(a^0y1<8(6xZd<33g*?1EG%nk-3y3Pa&tu6nS12(IQsF>r4dgkT1s|q ziMc}4z(tG!AkhdZew-(Lg4E>1sLOC1!V&N8G87vwZEmg#a!ie=oi5S{QpH?bcS-E!RF&gTXHg@eEVf2>~tuWLTQqDf(M$F(?TZ$dn9Go?* z6Mv~8wC=rgR0+L<2X4}jM&W)-M`WzHrxb5_Oe?Udo**_5O^)+`*adgqssAmm@m#=c zO#-LHhtlv1vew~RR$7EM(|ztZgY*Jx%u@BXM9gYCuEYd}118X%BGTqHG!+x9VX)hN zgS|uhAqOPwPLv3tZuw_ff8a&R;#Wl7*vSDwQevqo&0X7-m9S%P^#P)<9Mzr+JxV){ z@BPFYPayji=@r|X5qbk=!)Wzf4X;cmLbZ+{)1i^KVB$4SuO!oRYf%Dm3pE|wdgE2c z8=jgrf!N{+~ZTTR0-EyU7WFuZSATJW16l+e)31J+%(`Y-mP+!d- z&%J((=tyV>%z^ynq&;eWIr&mq|AKrVXU#9oFUSgVdiLd_`{iN=34K>yA-MVRQS08! zclTxnMAx1%|_**!*l9~|cP{8ofJzRM3Sb@YcH|pcOG!IO<;Q?%E2?!$0 zE)S(Vd$pVhs1E>SOD<|j8MaJ-S|HlY;%gb{i4N1QML-Skr*XSZ8V4sW=+xyj(VWnP zR`P8OPA8NFr6`|!0E~(Rzd|Wv$i&N;h*VgYWcf*m#s31i#2EL_NsCU(`G+#tB7ufx z4Dg^DPy3evsu(oCHhP%+v|?7@;D}U1*%^RHjt(%in|C}yYzi(Gb9A87?-$Rwy2#OF zbFP{KCP^3*MENUj+?YKYzP@)4S8d)yBBFcu!jtLWBWCgRC%qUnfX-9N_%0r=aL)!( zY86|oLYJ!!1(2ww5)IrR#fmbqoDSJJM_6UeDqTP&T z7hhriD-aefP3NCy4nmr0T%i90t*?V*g? zq0~=Pdx*t!YCa`C@N@}G{@CVHe$wKbUntJx6^68l3opN(R2X@)sN(3s@3IQ5$TEcM180D>?-S1!XP1A++Vn>tE46qWZIBU)49Ze!7c@dT z_yHgS#uJa7e3G%rEM$Z*s%ylHFpi3{KGKjdOc05V zAfV4Lk)#5-Pntc1H!v8{P)B_Fo46AI{yGUZgC_gQYVTyI;IT@7zVsALQ#<XM2I0)wBoA4S8zXamVNJ=ToyqOGRDDDHmli=NDVg6UqABp0e-Q(mV*JGraVx2z#u8 zSPh9EAnePls~6uvhHzcH!6U<@g6agRlCzt7NJ}6M7Ad?!OtQH6BR1NRIr!m^(0-;n zX=!Eh+@XKEBk~bM<;@GTZ@wcAUKEk_sdyDH6;gxC=~ZH`;ufSr(Ucw5HCV;L8k8TW zggY%pChc094K`%TdBz?S zq<%Zy9|T;{PcN7mUcjh;iH9SLM_-PvZNRM&s}v8 zp*0M`^rs9Q$&t{h=BaN{G&Vz61~F;UPI8xZjP}r64qzzFErOKKC`OC5px}Tum9i88 z0hoMXUFkd+-Ma`h%Ic+fu&xXb%1$w>ap)fxjYYBlDfk)l5{km*Fu7=MpMcBVPy;cF z#C;>gvd*yO{Njt_iX%P`SPq+HZcvuD|O2{jTuIWw3+g8~$k@Y#ai?Hqz8QR{&g zSVLlihdf&h;Sz`j9pn+8u60xC!#E5#kK-||=~ZcZW;Rovm~n6d62iGgV?p3Vd5N{X z1xvVjg9p9Y9kz`j!f56mjoC_G_nT&@g|w3Lle?>koSx%7(_a6hax4lnHNUYxCK>yzW$qgDQbSDX|FU}Le;z#+Yrym_ zg-1*`I*lW?aJV-Q3tMt@9B?3R<0W231!3`@M{@DhO-z@m;=0&BINnzf+H%Gn5(~KC z4-LGFegjJG&d=w?!vE*d-B~fL5Cn1p2g4_12}M>+X658&2(8My|GDdf=jDd7v?IeQ zzI5b3<`s(?ju=0t9@!sCR!>k74*LX4G^IV$b(GTxA152Z5u&k;&{>t!2p=aKpH~0~q-@HZ1@r&mH6fR7 zZXp2^GURLJ(ijpD*K-0usuv6M@;{MVxvJN?R~<@XCL{zG=o?&_P}efLy6E;%zhl(- zM7vozm%FnD?T7^q`LVV@ljaCK7VL7ZO%IER>}6lyu>8 zoRvBMvPCz)rEAvDAa$HOk~bOk&x>+O>Q=&qSjxh{)n{790a52|lhX86L=N~R+UNp> zxP6C+r|uyJ6Lxb96IUb&bNiLV<8?qj-;o_37n>yUAWoNET)^&@pCybn{3zf1?QMKZ}IgA2FVzqIim5}wKGbE*kZSw=j3RMP0TD-#RjU7lu43kV>HvS zqYBY=m^L8ZcQuWPUY^u*HqR<|;x+QVh7_pdI~i<66OtD#!7Jn=dK|TpV_bVqAqnqX z=nCTm?V|^>ee?)t$_o7IIt_sC$ zfFaYsJrwm2f{pZo)wqkFXpQ}5S^i}AKXeO7T|cO6l@$Q-@hdSAqxwImBE*CQ+Mbt% z+jR;PA@dBuA(>|nG@R2WD>F-(@CDDjHxJtyA|)mF^@FuRRGi`xE5sWXSKM$c_7K@g zE4?ulsENy3Yo;I!0*=*PCl_sdahYlm6WO;oxYy|CawDnOQ1|z540=O~3aE zi4EuQx0G{z#ER5KAdk(0(Fr z0Gf-mJl=^U8|5nPa`lE)wOSkmyiEp~?f3I!4rR25MaQ zkOwp_0!_ork_s{odw3}DRDjJJ3Ey$Wy#_866R^0!g6k?T2Xblz_ptFkh*A;h6G$QR zr%fE~f^Kh^j0yuPsMg&!l5B>jj8s@KfCG->_fn0doJDacb~6lz@;4g^bcVArBLN}> zzoE%2exrAj@EeL5RL0BXi4d+aRlMIGo!-BA-?=~P4)33Wl<{wK?nH#j{OMo>J7Ee} z!m<=5B9vfJX6(bRz%Z|zZ{wnUZf#r+2lu=E(`NTRlJ^eUp{)Tpb`J9#wZpQB{xT5t zFGk7ME(ZV)|IFpVpXvMB(hB2b7-Fo<=MD5m1&qiAAHEeD#vwfBG%FdZ)*;CWX4Xw%!%CsT7?K9G&9FRhssmp6nXoI}yXWNHx843pC^}!f z{~h8ACrA|6r~x=e@HoK=@uG0G)~!=nEoOcMxd$t9{A!b184IO#Yggs~YFws_D|5h9 zcjp-pR_bL7~r1ARo%&pP5w6Z7S)Ph2VPSgtbs~J}nw_4+FYwJZFb7>5Y zDQohjk6bN?!of7NmE?6kzF|@|_q|B5cidFqqN_*|s5alU5glM;eP`N60fKPL9bVbj zxkr49*xo1~+{^x@&!WmS`TI}zd8rbjjuCJC=8Xgl7jP};dZRpt>qD34zJIW^AeT*^ zHhbK69|8dElVkS}G=5%)1YN;q1!q`i3m@BDc>2A!C_B7_N`a_sMlfGq;KI>Xo7Xp? z>*EG4T0}yAiDz+R(Zm{xH@iy(Xmc(wNN&L-a25QPp;+mp-|xQxCS~p{&(DxqMqHuJdMKkjMI}Oc+dgtdx2ec$ltv`ex?g$`}ffFbGp{Ao&0~ zJ^e2JBfp1m9cf{tuDP2qLLPB|%}79U1d84<>oTQLW@SaHfOOA>qIo*r+9*6icG89K z7sPjxuY)GUo*_pl~?WI_-YT9md92D_>`e} zy**s`r^b5u3tKeQjv`w;P%tKgQ_F%zfTh>d@IF!5wn1 zfR}8ybYFx26I&VZwjw+OD;54lz`t%3afbb^KE>aDEzXNm)(&83m6`cs>D9vA53lbb z02!Vdp&ThDPAh-iMT9BzavrZVr4qsmXYf$skU<>@AcTsHOx(ak$`NObryDoGQt{#Z z^8E7LKkp530d)H_Z_--)*9@qLJ2aE)J(zzmxA@>5SoxoqsP@mB)molkT$o$Dgeo<< zT;^e>A6V~NK8XpzM7P+7xK{+zHiWrz1H&?J?as23L!hn_79k-k#x&(HASrHF7e?FF z#q~lJyoFj{}V_^euQe5{mrH=frj4-XeMm#g(>YljQn zU!K=5zHimeKJE7EONaGm?`rk($I8NP?X=#iRS&j4S8&_>^Y_mxjr!(pwSHEvH8wxD z7IrHK_2<7dx|@~CLSwo5zEN$I8>sv2LuH|S)u=Z%p1)|-8&4Jkjisx_ z+UDW=lP5c$>*tGyjpei9%kzuPdVO(ix7=FWX*4#U_gc%<)r;C*`G<0A`C0RH>Dj+4 zjmGZt_uZ$@YnzQqeYe+IxN7Wl4?i82Tf^4*vq7V`);W2<_@MgqV(qZ}tXJzEu0MaV zyIVOQUNxUQdwTNZ;;ixc{nh&U?!)KrE6sy4c0cQfdncRkKi5%r=UwGNwNY6+d~bE@ zi@TMD(?s2u%kLN4-HR8kjWx8@T|DTb?}Ocky9dKx4!V`i)B57Z;X-SpzP$OgzR>OL zEL19$`o&tk+wHvkyjwllyckt_jh&Om;rA~;KRakQaHsM4)!EMCvyU&|Z7rTW*?h74 z;sWoV4QutY#=-N8W~E$Tto1I|S__Ny=P%B7E9K4QTD`K?T5R>6*EiR`=D+p#UsrE( zUuDpcwc9wuh0FDiwMJ#LUH_q60o?8L(f62>53QxvyV{GhjrRM^U!I@0_8RY>tsMaG z&BbR=YK>>ht%X+apboNXY(A@$pY7E?UI335gO^K-eZkMu$^qv6d(3;2^V;Y&cI)pq zmn%PdOAcCy^se%|Q*QeFC?Sv@#gdb#j$ zt$r|CubiJPwBMqi#lz7-<8-0bxOfSA0R3L9k%mssD^E|J9(F)eA77q7+{OE+jTf!n z;X>mgpNBWe!{D{<`uh9IGWe5ax1S&U@a*|}@NpSD@NTz%veEkGptkn%<-*}*^F?>F z+FPsD7b;gL@7DHD>(4&zb~m5zzH2O=E?hjX_nv>)+gv-VJo(}3d9VIUYoT%2SpQ+~ zWp%i8*n>oQa!PcR%5aC;pM@@+RO8+wc5cC-|sfowsyPyLH%>3 zR^5Eo++C`Jw=2(@-L-!oJ~{h$bG85Rq<+=g={9z2pBoQPH`WezKfhnDEVVxG9bE0T zHV%KOpC4}RZEWt=-aY&9vU~R8^mApe_4Hz)R$g4JY#eqEmp4D2zB_wgdGhSj&gaTm zZF%RxdT(uT__T4c+i0A%7Awu>GWhw$+D^TEcC~x3yW1=uK0T?ef@)tbK3}-{u(SE{ zQ~k;FhrcY0)=rj2&riE+?`rQF+qLqj`?A+x28NV{t#n$+IoLhf4SV`Ppb^`S3;i z$-{+qz5A@yJ%nsuTnAr1ZFV>RjrrYuelQaHJ}ftu>-F7Tyjxy>-vGm199A0_&p?Bn z-ObHjrT%RFd1Dj2)apKmYzE~~HovbtZ9%4S-8lRJSyWdZKC402m+^ZWzk8>Up_Tf} zU!He2-{IN6pVuF*A1;j`OGg)#&)wyn^0T#iqwxfN?_+&pdrx5J~W%DclS&G%PV2b*W_pC3H?aQbxZ#mUkx==b?jW#Rc% zdt>MG^QF;n9k@E}T|C`h7(J*T{Lsg{Pu26rRdea=S?%Dee6obKrTnku=2H3dUUjtp zvUYZ{(>r{Dwd`TDTYvDpak11`0G@h{t(UdRCgjA!%IDKxPBu?JJwMp&y{sQ@SKjY_ z+G|uU4>l|3;M)h_>CKnDm&?_~!^-YC#{J}U@pPk6YxdS&R5!|l+KckXo#jUL|6}h> zn^ecHMA7g171_SNams}F3dW`QR{@|GMt>P zju8vGxD-l_b~q^qTtpdNk`hB1XlWrDEnKo_yR!z^a$3jzT7~{Xb`LnQTt{sm)B>Su92e_Ies{*V6IU&5-7Qhx;?EzZkwGHG6gJ@@~w05n1K>I2X^ps7`-Qa^z%-Zy5@solT0 zN)(Wl4!CM4Yg6@9JN|d;K&R>ngcDW9{oCe2BnFB}{^@^0kwTQP9;O9PkQ)0z5P?9_ z$G;xC12>MV(@WJ&2PA+$f%#)&?tg);cjNyjaRZcV%Z1pgUmW*O-yS~(Gkx_jh&2f2 zs&@|}(YL?7hrQo^`t2{jzCiUF*E2&@R*_hW?H31%uD_rP)hKb+{|B@8AXt01|H})4 zB~b4~M-&(hp*r4AhCq7WM_L_yD_BMXC9qHAGL)4LrTXWSB4D+3;4!KAlf3|N-tFg#9PbXp;OYi9Z*N0NwW~+n zJ?~(plZF~)cf?pZV%0(0V1!0S_L+Nj!(V@81V-i9h;PB)r;I z&@`T>V1~d-{4>K7Gcdb2YKH&J;FQcOJVngDF#hxK6-E4K#%5%BE`MR* z_j`Ubp}ZbfMf~oE_JuYsRY@Cz zFpS-?0ss?8B3C?v94D*S)vZOZs{4O`e7jHR&Fy~PUseELb%*%z`{OGpq8C@dzQ3wL z1-+@k?*0OuBzlY>;{LGOXY{l>F?jr=r2{uz7pr)wQ7(blt%}LpfbI7c?><8Wu%h(` zpSdbkSo2zT;-h1QZAU2((#LTX^x!roh&s3G0b%9*bR#2wd@9i8)fvC;2{!0zV?-PD zqb))x|Mv5|T_5b!JMwUcoUh#5+al`$pO^Y&O7o_h=U#45`A6sT+|QTM|C`yo+n+yx z${#vVB90e%GA+j^0zC3$NFF@9TNlpxCWDuG9P9PVfiq zA&(SH^SLkZa!vW@7y>G(O{_*{HpgO-M`#&F$$FP}(p=^52~}FwLlldA;?--VthL#`}`FKVfiA zRkH`}2inkj3qE)W>AK!+$DK!b+Ks=Vef~S-lzbTFDlWYr;i~<3-+RUFexc_Zq5Ww3 zw|5`S{>BG?VTh~T_I~nL4aWP)SIqGjdcKQ(@B6+hDBkye<(a?G|4n{;-~CMq@xJ$~ z3ivIAe{`m`4Enz7TFdahV?<=XFz2fj`@Y|+8sUA%70>-?&)>yY$~Hda$$Wp+A5?du zva(z;3KAA;o#6upd_YnN-+&NanIvm00XXv;dpMwQi4U$QLdsN)He~l0f|QN0^B)

-pdcH8?i*q0*|&2>G#cg7TyQsvsEGqkIRp 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 Date: Fri, 3 Nov 2017 14:33:07 +0700 Subject: [PATCH 016/118] Improve add-on file locator --- dev-scripts/docker/find-addons2.sh | 2 +- src/addons/DevHelper/Router.php | 35 ++++++++++++++++++++------ src/addons/DevHelper/StreamWrapper.php | 11 ++++++-- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/dev-scripts/docker/find-addons2.sh b/dev-scripts/docker/find-addons2.sh index 9e5e7d1..8dd64fb 100644 --- a/dev-scripts/docker/find-addons2.sh +++ b/dev-scripts/docker/find-addons2.sh @@ -6,5 +6,5 @@ cd /var/www/html/ { \ echo "# Generated by $0"; \ - find addons/ -maxdepth 5 -name addon.json -type f | sed 's#/addon.json##'; \ + find addons/ -maxdepth 5 -path '*.git' -prune -or -name 'addon.json'; \ } > ./xenforo/internal_data/addons2.txt diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php index 0ae8867..64a44e3 100644 --- a/src/addons/DevHelper/Router.php +++ b/src/addons/DevHelper/Router.php @@ -118,17 +118,21 @@ public static function locate($fullPath, &$success = null) $fullPath ); + $srcAddOnsPath = null; + if (strpos($shortened, static::PATH_SLASH_SRC_ADDONS_SLASH) === 0) { + $srcAddOnsPath = substr($shortened, strlen(static::PATH_SLASH_SRC_ADDONS_SLASH)); + } + foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { $candidatePaths = []; - if (strpos($shortened, static::PATH_SLASH_SRC_ADDONS_SLASH) === 0) { - $relativePath = substr($shortened, strlen(static::PATH_SLASH_SRC_ADDONS_SLASH)); - if (strpos($relativePath, $addOnPathSuffix) === 0) { - $candidatePaths[] = $addOnPath . '/' . substr($relativePath, strlen($addOnPathSuffix)); - } elseif (strpos($addOnPathSuffix, $relativePath) === 0) { + if ($srcAddOnsPath !== null) { + if (strpos($srcAddOnsPath, $addOnPathSuffix) === 0) { + $candidatePaths[] = $addOnPath . '/' . substr($srcAddOnsPath, strlen($addOnPathSuffix)); + } elseif (strpos($addOnPathSuffix, $srcAddOnsPath) === 0) { $parentPathSuffix = dirname($addOnPathSuffix); $parentPath = dirname($addOnPath); - if (strpos($relativePath, $parentPathSuffix) === 0) { + if (strpos($srcAddOnsPath, $parentPathSuffix) === 0) { $candidatePaths[] = $parentPath; } } @@ -154,6 +158,14 @@ public static function locate($fullPath, &$success = null) } } + if (!$success && $srcAddOnsPath !== null) { + $candidatePath = '/var/www/html/addons/' . $srcAddOnsPath; + if (file_exists($candidatePath)) { + $success = true; + return $candidatePath; + } + } + return $fullPath; } @@ -161,11 +173,13 @@ public static function getLocatePaths() { static $xenforoDir = null; static $addOnPaths = null; + static $addonsDir = null; if ($addOnPaths === null) { $routerPhp = $_SERVER['DEVHELPER_ROUTER_PHP']; $routerPhpDir = dirname($routerPhp); $xenforoDir = sprintf('%s/xenforo', $routerPhpDir); + $addonsDir = sprintf('%s/addons', $routerPhpDir); $addOnPaths = array(); $txtPath = sprintf('%s/internal_data/addons2.txt', $xenforoDir); @@ -186,13 +200,18 @@ public static function getLocatePaths() continue; } - $addOnPath = sprintf('%s/%s', $routerPhpDir, $line); + $lineWithoutAddOnJson = preg_replace('#/addon.json$#', '', $line, -1, $count); + if ($count !== 1) { + continue; + } + + $addOnPath = sprintf('%s/%s', $routerPhpDir, $lineWithoutAddOnJson); $addOnPathSuffix = trim(preg_replace('#^.+addons#', '', $addOnPath), '/'); $addOnPaths[$addOnPathSuffix] = $addOnPath; } } - return array($xenforoDir, $addOnPaths); + return array($xenforoDir, $addOnPaths, $addonsDir); } public static function locateReset() diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php index 76fe106..3161a18 100644 --- a/src/addons/DevHelper/StreamWrapper.php +++ b/src/addons/DevHelper/StreamWrapper.php @@ -121,8 +121,11 @@ public function mkdir($path, $mode, $options) { $located = static::locate($path); if (!file_exists($located)) { + list($xenforoDir, , $addonsDir) = Router::getLocatePaths(); $locatedDir = static::locate(dirname($path)); - if (is_dir($locatedDir)) { + if ($locatedDir === $xenforoDir . '/src/addons') { + $located = $addonsDir . DIRECTORY_SEPARATOR . basename($path); + } elseif (is_dir($locatedDir)) { $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); } } @@ -171,6 +174,10 @@ public function stream_close() fclose($this->_streamHandle); + if (basename($this->_streamPath) === 'addon.json') { + Router::locateReset(); + } + $this->_streamPath = null; $this->_streamHandle = null; } @@ -368,7 +375,7 @@ public static function locate($path) } $pathWithoutProtocol = substr($path, $protocolLength + 3); - list($xenforoDir,) = Router::getLocatePaths(); + list($xenforoDir) = Router::getLocatePaths(); $pathFromRoot = $xenforoDir . DIRECTORY_SEPARATOR . $pathWithoutProtocol; return Router::locateCached($pathFromRoot); From 4d4a838e04071f4812ef9f9a8aeeab21a0e18a7d Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Fri, 3 Nov 2017 14:33:27 +0700 Subject: [PATCH 017/118] Docker version bump (php v7.1.11) --- dev-scripts/Dockerfile.php-apache | 25 +++++++++++-------------- router.php | 6 ++++++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index 85b8a31..8e64cfd 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -1,22 +1,19 @@ -FROM xfrocks/xenforo:php-apache-7.1.8 +FROM xfrocks/xenforo:php-apache-7.1.11 -RUN apt-get update && apt-get install -y \ - npm \ - && a2enmod rewrite \ - && npm install uglify-js -g \ - && pear install PHP_CodeSniffer \ - && rm -rf /var/lib/apt/lists/* +RUN pear install PHP_CodeSniffer; \ + pecl install apcu; \ + docker-php-ext-enable apcu -RUN pecl install apcu \ - && docker-php-ext-enable apcu +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017110301 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh -RUN mv /usr/local/bin/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key \ - && chmod 0640 /etc/ssl/private/ssl-cert-snakeoil.key \ - && mv /usr/local/bin/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem \ - && chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem \ - && a2enmod ssl && a2ensite default-ssl +RUN echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-available/env.conf; \ + mv /usr/local/bin/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key; \ + chmod 0640 /etc/ssl/private/ssl-cert-snakeoil.key; \ + mv /usr/local/bin/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem; \ + chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem; \ + a2enmod env rewrite ssl && a2ensite default-ssl CMD ["/usr/local/bin/cmd.sh"] diff --git a/router.php b/router.php index 563c29a..df406c3 100644 --- a/router.php +++ b/router.php @@ -1,4 +1,10 @@ Date: Wed, 15 Nov 2017 16:18:50 +0700 Subject: [PATCH 018/118] Remove locateReset call in Admin Manager --- src/addons/DevHelper/XF/AddOn/Manager.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/addons/DevHelper/XF/AddOn/Manager.php b/src/addons/DevHelper/XF/AddOn/Manager.php index 3cf7191..cdaa154 100644 --- a/src/addons/DevHelper/XF/AddOn/Manager.php +++ b/src/addons/DevHelper/XF/AddOn/Manager.php @@ -6,12 +6,6 @@ class Manager extends XFCP_Manager { - protected function getAllJsonInfo() - { - Router::locateReset(); - return parent::getAllJsonInfo(); - } - public function getAddOnPath($addOnId) { $addOnPath = parent::getAddOnPath($addOnId); From 61367f177f0bd0d9691828d25d8f72fa19f32796 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 15 Nov 2017 16:33:53 +0700 Subject: [PATCH 019/118] Remove locateReset call in Admin Manager (attempt 2) --- src/addons/DevHelper/StreamWrapper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php index 3161a18..ec7b012 100644 --- a/src/addons/DevHelper/StreamWrapper.php +++ b/src/addons/DevHelper/StreamWrapper.php @@ -11,6 +11,7 @@ class StreamWrapper private $_dirSecondHandle; private $_streamPath; private $_streamHandle; + private $_streamWritten; /** * Close directory handle @@ -174,12 +175,13 @@ public function stream_close() fclose($this->_streamHandle); - if (basename($this->_streamPath) === 'addon.json') { + if (basename($this->_streamPath) === 'addon.json' && $this->_streamWritten > 0) { Router::locateReset(); } $this->_streamPath = null; $this->_streamHandle = null; + $this->_streamWritten = null; } /** @@ -267,6 +269,7 @@ public function stream_open($path, $mode, $options, &$openedPath) $this->_streamPath = $path; $this->_streamHandle = fopen($located, $mode); + $this->_streamWritten = 0; return true; } @@ -322,6 +325,7 @@ public function stream_write($data) } $written = fwrite($this->_streamHandle, $data); + $this->_streamWritten += $written; return $written; } From f1e3087ead55819954e816c4a23ce1d54ab32511 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 15 Nov 2017 16:33:59 +0700 Subject: [PATCH 020/118] Delete addon.json --- src/addons/DevHelper/Autoloader.php | 2 ++ src/addons/DevHelper/XF/Extension.php | 12 ++++++++++++ src/addons/DevHelper/addon.json | 15 --------------- 3 files changed, 14 insertions(+), 15 deletions(-) delete mode 100644 src/addons/DevHelper/addon.json diff --git a/src/addons/DevHelper/Autoloader.php b/src/addons/DevHelper/Autoloader.php index 4716f7a..ac9f3e3 100644 --- a/src/addons/DevHelper/Autoloader.php +++ b/src/addons/DevHelper/Autoloader.php @@ -22,6 +22,8 @@ public function setupAutoloader() /** @noinspection PhpIncludeInspection */ $autoLoader = require('/var/www/html/xenforo/src/vendor/autoload.php'); + $autoLoader->setPsr4('DevHelper\\', __DIR__); + list(, $addOnPaths) = Router::getLocatePaths(); foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { $globPattern = $addOnPath . '/src/addons/*'; diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php index f81ddcc..0a199c8 100644 --- a/src/addons/DevHelper/XF/Extension.php +++ b/src/addons/DevHelper/XF/Extension.php @@ -20,6 +20,18 @@ public function __construct(array $listeners = [], array $classExtensions = []) { parent::__construct($listeners, $classExtensions); + $this->initDevHelper(); + } + + private function initDevHelper() + { + static $initOk = false; + if ($initOk) { + return; + } + $initOk = true; + + require(dirname(__DIR__) . '/StreamWrapper.php'); stream_wrapper_register(StreamWrapper::PROTOCOL, StreamWrapper::class); XF::setSourceDirectory(StreamWrapper::PROTOCOL . '://src'); diff --git a/src/addons/DevHelper/addon.json b/src/addons/DevHelper/addon.json deleted file mode 100644 index b7d5ee7..0000000 --- a/src/addons/DevHelper/addon.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "legacy_addon_id": "", - "title": "Developer Helper Tools", - "description": "", - "version_id": 2000000, - "version_string": "2.0.0", - "dev": "", - "dev_url": "", - "faq_url": "", - "support_url": "", - "extra_urls": [], - "require": [], - "icon": "", - "addon_id": "DevHelper" -} \ No newline at end of file From 1399a7739c7aea3fe3a090642a3bf6e16bcc6c8f Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 22 Nov 2017 09:55:32 +0700 Subject: [PATCH 021/118] Add support for cmd.php xf-addon:xxx shortcuts --- dev-scripts/Dockerfile.php-apache | 22 +++++++++++++++++++++- router.php | 4 ++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index 8e64cfd..d8a2138 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -4,7 +4,7 @@ RUN pear install PHP_CodeSniffer; \ pecl install apcu; \ docker-php-ext-enable apcu -ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017110301 +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017112201 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh @@ -16,4 +16,24 @@ RUN echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-availabl chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem; \ a2enmod env rewrite ssl && a2ensite default-ssl +RUN for verb in build-release \ + bump-version \ + create \ + disable \ + enable \ + export \ + install \ + install-step \ + rebuild \ + sync-json \ + uninstall \ + uninstall-step \ + upgrade \ + upgrade-step \ + validate-json \ + ; do \ + printf -- "%b" "#!/bin/bash\nphp /var/www/html/cmd.php xf-addon:${verb} \"\$@\"" >/usr/local/bin/xf-addon--${verb} && chmod +x /usr/local/bin/xf-addon--${verb} \ + ; done + +WORKDIR "/var/www/html/addons" CMD ["/usr/local/bin/cmd.sh"] diff --git a/router.php b/router.php index df406c3..272601f 100644 --- a/router.php +++ b/router.php @@ -1,10 +1,10 @@ Date: Sun, 3 Dec 2017 15:22:17 +0700 Subject: [PATCH 022/118] Improve php.cmd shortcuts --- dev-scripts/Dockerfile.php-apache | 19 +-------------- dev-scripts/docker/build.sh | 27 +++++++++++++++++++++ dev-scripts/docker/cmd-php--xf-addon.sh | 17 +++++++++++++ dev-scripts/docker/cmd-php.sh | 5 ++++ dev-scripts/docker/xf-addon--create.sh | 5 ++++ dev-scripts/docker/xf-dev--export--addon.sh | 11 +++++++++ 6 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 dev-scripts/docker/build.sh create mode 100644 dev-scripts/docker/cmd-php--xf-addon.sh create mode 100644 dev-scripts/docker/cmd-php.sh create mode 100644 dev-scripts/docker/xf-addon--create.sh create mode 100644 dev-scripts/docker/xf-dev--export--addon.sh diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index d8a2138..c71fb3d 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -16,24 +16,7 @@ RUN echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-availabl chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem; \ a2enmod env rewrite ssl && a2ensite default-ssl -RUN for verb in build-release \ - bump-version \ - create \ - disable \ - enable \ - export \ - install \ - install-step \ - rebuild \ - sync-json \ - uninstall \ - uninstall-step \ - upgrade \ - upgrade-step \ - validate-json \ - ; do \ - printf -- "%b" "#!/bin/bash\nphp /var/www/html/cmd.php xf-addon:${verb} \"\$@\"" >/usr/local/bin/xf-addon--${verb} && chmod +x /usr/local/bin/xf-addon--${verb} \ - ; done +RUN /usr/local/bin/build.sh WORKDIR "/var/www/html/addons" CMD ["/usr/local/bin/cmd.sh"] diff --git a/dev-scripts/docker/build.sh b/dev-scripts/docker/build.sh new file mode 100644 index 0000000..b8f699d --- /dev/null +++ b/dev-scripts/docker/build.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +for _verb in build-release \ + bump-version \ + disable \ + enable \ + export \ + install \ + install-step \ + rebuild \ + sync-json \ + uninstall \ + uninstall-step \ + upgrade \ + upgrade-step \ + validate-json \ + ; do + _verbPath="/usr/local/bin/xf-addon--${_verb}" + { + echo '#!/bin/bash'; \ + echo; \ + echo 'set -e'; \ + echo; \ + echo "exec cmd-php--xf-addon.sh ${_verb} \"\$@\""; + } >"${_verbPath}" + chmod +x "${_verbPath}" +done diff --git a/dev-scripts/docker/cmd-php--xf-addon.sh b/dev-scripts/docker/cmd-php--xf-addon.sh new file mode 100644 index 0000000..50f13fb --- /dev/null +++ b/dev-scripts/docker/cmd-php--xf-addon.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +_verb="${1}" +if [ -z "${_verb}" ]; then + echo 'Verb is missing' >&2 + exit 1 +fi + +_addOnId="${2%/}" +if [ -z "${_verb}" ]; then + echo 'Add-on ID is missing' >&2 + exit 2 +fi + +exec cmd-php.sh "xf-addon:${_verb}" "${_addOnId}" diff --git a/dev-scripts/docker/cmd-php.sh b/dev-scripts/docker/cmd-php.sh new file mode 100644 index 0000000..bebe938 --- /dev/null +++ b/dev-scripts/docker/cmd-php.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +exec php /var/www/html/cmd.php "$@" diff --git a/dev-scripts/docker/xf-addon--create.sh b/dev-scripts/docker/xf-addon--create.sh new file mode 100644 index 0000000..9c67d55 --- /dev/null +++ b/dev-scripts/docker/xf-addon--create.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +exec cmd-php.sh xf-addon:create diff --git a/dev-scripts/docker/xf-dev--export--addon.sh b/dev-scripts/docker/xf-dev--export--addon.sh new file mode 100644 index 0000000..59e6015 --- /dev/null +++ b/dev-scripts/docker/xf-dev--export--addon.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +_addOnId="${1%/}" +if [ -z "${_addOnId}" ]; then + echo 'Add-on ID is missing' >&2 + exit 1 +fi + +exec cmd-php.sh xf-dev:export --addon "${_addOnId}" From e36031a2e85e2d9d01d5761892efdaa24fb25ae1 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Wed, 6 Dec 2017 10:29:50 +0700 Subject: [PATCH 023/118] php7.2 --- dev-scripts/Dockerfile.php-apache | 4 +- dev-scripts/helpers/create.php | 71 --------------- dev-scripts/helpers/help.php | 23 ----- dev-scripts/helpers/quit.php | 5 -- dev-scripts/helpers_includes/common.php | 38 -------- dev-scripts/xf-compatibility-check.sh | 114 ------------------------ dev-scripts/xf-find-new-addons.sh | 34 ------- dev-scripts/xf-helper.php | 95 -------------------- dev-scripts/xf-new-addon.sh | 76 ---------------- dev-scripts/xf-setup-root.sh | 19 ---- router.php | 10 ++- 11 files changed, 8 insertions(+), 481 deletions(-) delete mode 100755 dev-scripts/helpers/create.php delete mode 100755 dev-scripts/helpers/help.php delete mode 100755 dev-scripts/helpers/quit.php delete mode 100755 dev-scripts/helpers_includes/common.php delete mode 100644 dev-scripts/xf-compatibility-check.sh delete mode 100755 dev-scripts/xf-find-new-addons.sh delete mode 100755 dev-scripts/xf-helper.php delete mode 100755 dev-scripts/xf-new-addon.sh delete mode 100644 dev-scripts/xf-setup-root.sh diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index c71fb3d..62944d5 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -1,10 +1,10 @@ -FROM xfrocks/xenforo:php-apache-7.1.11 +FROM xfrocks/xenforo:php-apache-7.2.0 RUN pear install PHP_CodeSniffer; \ pecl install apcu; \ docker-php-ext-enable apcu -ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017112201 +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120601 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh diff --git a/dev-scripts/helpers/create.php b/dev-scripts/helpers/create.php deleted file mode 100755 index 2cd5607..0000000 --- a/dev-scripts/helpers/create.php +++ /dev/null @@ -1,71 +0,0 @@ - $filePath) - { - echo " $helperFunction\n"; - } - } - else - { - echo "Requesting " . $PARAMS[0] . "\n"; - } -} -else -{ - if (count($PARAMS) <= 1) - { - $candidates += array_keys($GLOBALS['HELPERS']); - } -} \ No newline at end of file diff --git a/dev-scripts/helpers/quit.php b/dev-scripts/helpers/quit.php deleted file mode 100755 index df70233..0000000 --- a/dev-scripts/helpers/quit.php +++ /dev/null @@ -1,5 +0,0 @@ -getAddOnOptionsList(false, false)); - } - - public static function loadCachedModel($class) - { - static $models = array(); - - if (!isset($models[$class])) - { - $models[$class] = XenForo_Model::create($class); - } - - return $models[$class]; - } - - public static function parseCommand($command) - { - $parts = explode(' ', preg_replace('/\s+/', ' ', $command)); - - foreach (array_keys($parts) as $i) - { - if ($parts[$i] === '') - { - unset($parts[$i]); - } - } - - return $parts; - } -} \ No newline at end of file diff --git a/dev-scripts/xf-compatibility-check.sh b/dev-scripts/xf-compatibility-check.sh deleted file mode 100644 index d09ac54..0000000 --- a/dev-scripts/xf-compatibility-check.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/php -setupAutoloader($pathToXenForoRoot . '/library'); -XenForo_Application::initialize($pathToXenForoRoot . '/library', $pathToXenForoRoot); - -function checkFile($file) -{ - $contents = file_get_contents($file); - $offset = 0; - - while(true) - { - if (preg_match('/extends[^X]+(XFCP_[A-Za-z_]+)/', $contents, $matches, PREG_OFFSET_CAPTURE, $offset)) - { - $offset = $matches[0][1] + 1; - - $xfcpClassName = $matches[1][0]; - $parts = explode('_', $xfcpClassName); - array_shift($parts); // remove XFCP_ - array_shift($parts); // remove add-on prefix (if add-on has multiple prefixes, this is good enough to prevent processing our own file) - - $processingParts = array(); - $processed = false; - while (count($parts) > 0) - { - $part = array_pop($parts); - array_unshift($processingParts, $part); - $processingClassName = implode('_', $processingParts); - - if (class_exists($processingClassName)) - { - eval('class ' . $xfcpClassName . ' extends ' . $processingClassName . ' {}'); - - try - { - require($file); - } - catch (Exception $e) - { - echo sprintf("Exception: %s\n", $e->getMessage()); - } - - $processed = true; - } - elseif (strpos($processingClassName, 'XenForo_ViewPublic_') === 0) - { - // for XenForo_ViewPublic_* classes, if the view class itself cannot be found - // the system will load XenForo_ViewPublic_Base, we will check againts that now - eval('class ' . $xfcpClassName . ' extends XenForo_ViewPublic_Base {}'); - - try - { - require($file); - } - catch (Exception $e) - { - echo sprintf("Exception: %s\n", $e->getMessage()); - } - - $processed = true; - } - - if ($processed) - { - break; - } - } - } - else - { - break; - } - } -} - -function loop($dir) -{ - $nodes = glob(sprintf("%s/*", $dir)); - - foreach($nodes as $node) - { - if (is_dir($node)) - { - loop($node); - } - else - { - $ext = strtolower(pathinfo($node, PATHINFO_EXTENSION)); - if ($ext === 'php') - { - checkFile($node); - } - } - } -} -loop($pathToAddOnRepo); \ No newline at end of file diff --git a/dev-scripts/xf-find-new-addons.sh b/dev-scripts/xf-find-new-addons.sh deleted file mode 100755 index d48912f..0000000 --- a/dev-scripts/xf-find-new-addons.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -_xfPath=$1 -_repoPath=$2 - -if [ ! -d "$_xfPath" ]; then - echo "XenForo Path $_xfPath not found" >&2 - exit 1 -fi - -if [ ! -d "$_repoPath" ]; then - echo "Repo Path $_repoPath not found" >&2 - exit 1 -fi - -_extractVersionId() { - _filePath=$1 - _line=$(head -n 2 "$_filePath" | grep -o 'version_id="\d*"' ) - echo "$_line" - exit 1 -} - -find "$_xfPath" -type f -name 'addon-*.xml' | while read -r _xfFilePath ; do - _fileName=$( basename "$_xfFilePath" ) - _addOnId=$( echo "$_fileName" | sed 's/^addon-//' | sed 's/\.xml$//' ) - _xfVersionId=$( _extractVersionId "$_xfFilePath" ) - - find "$_repoPath" -type f -name "$_fileName" | while read -r _repoFilePath ; do - _repoVersionId=$( _extractVersionId "$_repoFilePath" ) - if [ "$_xfVersionId" != "$_repoVersionId" ]; then - echo "$_addOnId:\n\tXenForo $_xfVersionId\n\tRepo $_repoVersionId" - fi - done -done diff --git a/dev-scripts/xf-helper.php b/dev-scripts/xf-helper.php deleted file mode 100755 index b50ab56..0000000 --- a/dev-scripts/xf-helper.php +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/php -setupAutoloader($PWD . '/library'); -XenForo_Application::initialize($PWD . '/library', $PWD); - -// load our functions -@include($DIR . '/helpers_includes/common.php'); -if (!class_exists('Helper_Common')) -{ - echo "Corrupted script\n"; - exit(-1); -} - -function readline_completion_impl($string, $index) -{ - $readline_info = readline_info(); - $line = substr($readline_info['line_buffer'], 0, $readline_info['end']); - $parts = Helper_Common::parseCommand($line); - $candidates = array(); - - if (empty($parts)) - { - // no input yet, just return list of helper functions - $candidates += array_keys($GLOBALS['HELPERS']); - } - else - { - if (isset($GLOBALS['HELPERS'][$parts[0]])) - { - // we actually got the helper function correctly - $PARAMS = array_slice($parts, 1); - $IS_COMPLETION = true; - require($GLOBALS['HELPERS'][$parts[0]]); - } - else - { - // incomplete helper function... - $candidates += array_keys($GLOBALS['HELPERS']); - } - } - - return $candidates; -} -readline_completion_function('readline_completion_impl'); - -while (true) -{ - $command = readline('> '); - readline_add_history($command); - $parts = Helper_Common::parseCommand($command); - - if (empty($parts[0]) OR !isset($HELPERS[$parts[0]])) - { - $parts[0] = 'help'; - } - - $PARAMS = array_slice($parts, 1); - require($HELPERS[$parts[0]]); -} \ No newline at end of file diff --git a/dev-scripts/xf-new-addon.sh b/dev-scripts/xf-new-addon.sh deleted file mode 100755 index 2bb94f1..0000000 --- a/dev-scripts/xf-new-addon.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -set -e - -if [ $# -ge 2 ]; then - _addOnDirRelativePath="$1" - _xenforoRootDirPath="$2" - - _addOnDirRelativePath=$( echo $_addOnDirRelativePath | sed 's#_#/#' | sed 's#/$##' ) - if [ -d "${_addOnDirRelativePath}/repo" ]; then - # legacy support - _repoDirRelativePath="${_addOnDirRelativePath}/repo" - else - _repoDirRelativePath="${_addOnDirRelativePath}" - fi - - _xenforoMajorVersion=1 - _phpRelativePath="" - _xenforoRootDirPath=$( echo $_xenforoRootDirPath | sed 's#/$##' ) - if [ -d "${_xenforoRootDirPath}" ]; then - if [ -d "${_xenforoRootDirPath}/src/addons/" ]; then - _xenforoMajorVersion=2 - echo "XenForo 2 detected" - _phpRelativePath="src/addons/${_addOnDirRelativePath}" - else - if [ -d "${_xenforoRootDirPath}/library/" ]; then - echo "XenForo 1 detected" - _phpRelativePath="library/${_addOnDirRelativePath}" - else - echo './library or ./src/addons does not exists!' >&2 - exit 1 - fi - fi - else - echo "${_xenforoRootDirPath} does not exists!" >&2 - exit 1 - fi - - _doSubPath() { - _subPath=$1 - _path="${PWD}/${_repoDirRelativePath}/${_subPath}" - _gitignorePath="${_xenforoRootDirPath}/.gitignore" - _xenforoPath="${_xenforoRootDirPath}/${_subPath}" - - if [ ! -d "${_path}" ]; then - mkdir -p "${_path}" - fi - - if [ ! -e "${_xenforoPath}" ]; then - _xenforoPathDirPath="$( dirname "${_xenforoPath}" )" - if [ ! -d "${_xenforoPathDirPath}" ]; then - echo "mkdir ${_xenforoPathDirPath}..." - sudo mkdir -p "${_xenforoPathDirPath}" - fi - - echo "ln ${_path} ${_xenforoPath}..." - sudo ln -s "${_path}" "${_xenforoPath}" - sudo chown -h $USER "${_xenforoPath}" - if [ -f "${_gitignorePath}" ]; then - echo "/${_subPath}" >> "${_gitignorePath}" - fi - fi - - echo "Sub path ${_subPath} ok" - } - _doSubPath "${_phpRelativePath}" - _doSubPath "js/${_addOnDirRelativePath}" - _doSubPath "styles/default/${_addOnDirRelativePath}" - - if [ ! -e "${_repoDirRelativePath}/.git" ]; then - git init -- "${_repoDirRelativePath}" - echo "git init ${_repoDirRelativePath} ok" - fi -else - echo USAGE: $0 [addOnId] [path/to/xenforo/root] -fi diff --git a/dev-scripts/xf-setup-root.sh b/dev-scripts/xf-setup-root.sh deleted file mode 100644 index ab1b134..0000000 --- a/dev-scripts/xf-setup-root.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -PATH_TO_XENFORO=`pwd` -PATH_TO_REPO=$(cd `dirname "${BASH_SOURCE[0]}"` && cd ../../.. && pwd) - -# install DevHelper if haven't done that yet -cd $PATH_TO_REPO && $PATH_TO_REPO/DevHelper/repo/dev-scripts/xf-new-addon.sh DevHelper $PATH_TO_XENFORO - -if [ ! -e "$PATH_TO_XENFORO/docker-compose.override.yml" ]; then - ln -s $PATH_TO_REPO/DevHelper/repo/docker-compose.yml $PATH_TO_XENFORO/docker-compose.yml - ( \ - echo "version: '2'"; \ - echo ""; \ - echo "services:"; \ - echo " php-apache:"; \ - echo " ports:"; \ - echo " - "$RANDOM:80""; \ - ) > $PATH_TO_XENFORO/docker-compose.override.yml -fi diff --git a/router.php b/router.php index 272601f..69db1f8 100644 --- a/router.php +++ b/router.php @@ -1,9 +1,11 @@ Date: Sat, 9 Dec 2017 18:51:31 +0700 Subject: [PATCH 024/118] Fix xf-addon--install-step and similar --- dev-scripts/Dockerfile.php-apache | 2 +- dev-scripts/docker/cmd-php--xf-addon.sh | 6 ++++-- router.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index 62944d5..9b026ce 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -4,7 +4,7 @@ RUN pear install PHP_CodeSniffer; \ pecl install apcu; \ docker-php-ext-enable apcu -ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120601 +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120901 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh diff --git a/dev-scripts/docker/cmd-php--xf-addon.sh b/dev-scripts/docker/cmd-php--xf-addon.sh index 50f13fb..5702cee 100644 --- a/dev-scripts/docker/cmd-php--xf-addon.sh +++ b/dev-scripts/docker/cmd-php--xf-addon.sh @@ -9,9 +9,11 @@ if [ -z "${_verb}" ]; then fi _addOnId="${2%/}" -if [ -z "${_verb}" ]; then +if [ -z "${_addOnId}" ]; then echo 'Add-on ID is missing' >&2 exit 2 fi -exec cmd-php.sh "xf-addon:${_verb}" "${_addOnId}" +shift 2 + +exec cmd-php.sh "xf-addon:${_verb}" "${_addOnId}" "$@" diff --git a/router.php b/router.php index 69db1f8..3e5a360 100644 --- a/router.php +++ b/router.php @@ -1,7 +1,7 @@ Date: Sat, 9 Dec 2017 18:55:51 +0700 Subject: [PATCH 025/118] Integrate phpcs into xf-addon--export.sh --- dev-scripts/Dockerfile.php-apache | 9 ++++++++- dev-scripts/docker/build.sh | 1 - dev-scripts/docker/phpcs.xml | 23 +++++++++++++++++++++++ dev-scripts/docker/xf-addon--export.sh | 14 ++++++++++++++ dev-scripts/docker/xf-addon--phpcbf.sh | 7 +++++++ dev-scripts/docker/xf-addon--phpcs.sh | 14 ++++++++++++++ router.php | 2 +- 7 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 dev-scripts/docker/phpcs.xml create mode 100644 dev-scripts/docker/xf-addon--export.sh create mode 100644 dev-scripts/docker/xf-addon--phpcbf.sh create mode 100644 dev-scripts/docker/xf-addon--phpcs.sh diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index 9b026ce..1b0e83b 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -4,7 +4,14 @@ RUN pear install PHP_CodeSniffer; \ pecl install apcu; \ docker-php-ext-enable apcu -ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120901 +ENV PHP_COMPATIBILITY_VERSION 8.0.1 +RUN curl -Lo /tmp/PHPCompatibility.tar.gz "https://github.com/wimg/PHPCompatibility/archive/${PHP_COMPATIBILITY_VERSION}.tar.gz" \ + && tar -xzf /tmp/PHPCompatibility.tar.gz -C /usr/local/share/ \ + && phpcs --config-set installed_paths "/usr/local/share/PHPCompatibility-${PHP_COMPATIBILITY_VERSION}" \ + && phpcs -i | grep PHPCompatibility \ + && rm -rf /tmp/* + +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120902 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh diff --git a/dev-scripts/docker/build.sh b/dev-scripts/docker/build.sh index b8f699d..03d5d1c 100644 --- a/dev-scripts/docker/build.sh +++ b/dev-scripts/docker/build.sh @@ -4,7 +4,6 @@ for _verb in build-release \ bump-version \ disable \ enable \ - export \ install \ install-step \ rebuild \ diff --git a/dev-scripts/docker/phpcs.xml b/dev-scripts/docker/phpcs.xml new file mode 100644 index 0000000..a507983 --- /dev/null +++ b/dev-scripts/docker/phpcs.xml @@ -0,0 +1,23 @@ + + + */_data/ + */_no_upload/ + */_output/ + */node_modules/ + */vendor/ + *.min.js + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-scripts/docker/xf-addon--export.sh b/dev-scripts/docker/xf-addon--export.sh new file mode 100644 index 0000000..ad39fef --- /dev/null +++ b/dev-scripts/docker/xf-addon--export.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +_addOnId="${1%/}" +if [ -z "${_addOnId}" ]; then + echo 'Add-on ID is missing' >&2 + exit 1 +fi + +xf-addon--phpcs.sh "${_addOnId}" +echo 'phpcs OK' + +exec cmd-php.sh xf-addon:export "${_addOnId}" diff --git a/dev-scripts/docker/xf-addon--phpcbf.sh b/dev-scripts/docker/xf-addon--phpcbf.sh new file mode 100644 index 0000000..74bdb4f --- /dev/null +++ b/dev-scripts/docker/xf-addon--phpcbf.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +export PHPCBF=1 + +exec xf-addon--phpcs.sh "$@" diff --git a/dev-scripts/docker/xf-addon--phpcs.sh b/dev-scripts/docker/xf-addon--phpcs.sh new file mode 100644 index 0000000..c147958 --- /dev/null +++ b/dev-scripts/docker/xf-addon--phpcs.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +_phpcsXmlPath='/usr/local/bin/phpcs.xml' +set -- "--standard=${_phpcsXmlPath}" "$@" + +if [ -z "$PHPCBF" ]; then + set -- phpcs -s "$@" +else + set -- phpcbf "$@" +fi + +exec "$@" diff --git a/router.php b/router.php index 3e5a360..9afbd1e 100644 --- a/router.php +++ b/router.php @@ -1,7 +1,7 @@ Date: Sun, 17 Dec 2017 13:27:46 +0700 Subject: [PATCH 026/118] Integrate phpcbf into xf-addon--export.sh --- dev-scripts/docker/xf-addon--export.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dev-scripts/docker/xf-addon--export.sh b/dev-scripts/docker/xf-addon--export.sh index ad39fef..10943e3 100644 --- a/dev-scripts/docker/xf-addon--export.sh +++ b/dev-scripts/docker/xf-addon--export.sh @@ -8,7 +8,20 @@ if [ -z "${_addOnId}" ]; then exit 1 fi -xf-addon--phpcs.sh "${_addOnId}" +_phpcs=$( xf-addon--phpcs.sh "${_addOnId}" || true ) +if [ ! -z "$_phpcs" ]; then + echo "$_phpcs" + + _phpcbfSuggestion=$( echo "$_phpcs" | grep 'PHPCBF CAN FIX' ) + if [ ! -z "$_phpcbfSuggestion" ]; then + xf-addon--phpcbf.sh "${_addOnId}" + echo 'phpcs failed, phpcbf OK' + exit 2 + fi + + echo 'phpcs failed' + exit 1 +fi echo 'phpcs OK' exec cmd-php.sh xf-addon:export "${_addOnId}" From 6bbcfd2e8a2c834e47b28198f383e615a277e622 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Fri, 12 Jan 2018 11:34:43 +0700 Subject: [PATCH 027/118] php v7.2.1 --- dev-scripts/Dockerfile.php-apache | 22 ++-------------------- dev-scripts/docker/build.sh | 5 +++++ router.php | 2 +- 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/dev-scripts/Dockerfile.php-apache b/dev-scripts/Dockerfile.php-apache index 1b0e83b..4e7d033 100644 --- a/dev-scripts/Dockerfile.php-apache +++ b/dev-scripts/Dockerfile.php-apache @@ -1,28 +1,10 @@ -FROM xfrocks/xenforo:php-apache-7.2.0 +FROM xfrocks/xenforo:php-apache-7.2.1d -RUN pear install PHP_CodeSniffer; \ - pecl install apcu; \ - docker-php-ext-enable apcu - -ENV PHP_COMPATIBILITY_VERSION 8.0.1 -RUN curl -Lo /tmp/PHPCompatibility.tar.gz "https://github.com/wimg/PHPCompatibility/archive/${PHP_COMPATIBILITY_VERSION}.tar.gz" \ - && tar -xzf /tmp/PHPCompatibility.tar.gz -C /usr/local/share/ \ - && phpcs --config-set installed_paths "/usr/local/share/PHPCompatibility-${PHP_COMPATIBILITY_VERSION}" \ - && phpcs -i | grep PHPCompatibility \ - && rm -rf /tmp/* - -ENV DEVHELPER_PHP_APACHE_VERSION_ID 2017120902 +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2018011202 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh -RUN echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-available/env.conf; \ - mv /usr/local/bin/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key; \ - chmod 0640 /etc/ssl/private/ssl-cert-snakeoil.key; \ - mv /usr/local/bin/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem; \ - chmod 0644 /etc/ssl/certs/ssl-cert-snakeoil.pem; \ - a2enmod env rewrite ssl && a2ensite default-ssl - RUN /usr/local/bin/build.sh WORKDIR "/var/www/html/addons" diff --git a/dev-scripts/docker/build.sh b/dev-scripts/docker/build.sh index 03d5d1c..837d5ad 100644 --- a/dev-scripts/docker/build.sh +++ b/dev-scripts/docker/build.sh @@ -1,5 +1,10 @@ #!/bin/bash +set -e + +echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-available/env.conf +a2enmod env rewrite + for _verb in build-release \ bump-version \ disable \ diff --git a/router.php b/router.php index 9afbd1e..37dcec1 100644 --- a/router.php +++ b/router.php @@ -1,7 +1,7 @@ Date: Fri, 6 Apr 2018 13:03:16 +0700 Subject: [PATCH 028/118] Simplify Docker environment setup --- .gitignore | 1 + .htaccess | 2 - Dockerfile | 8 + README.md | 162 -------- addons/.gitkeep | 0 cmd.php | 4 - dev-scripts/Dockerfile.php-apache | 11 - dev-scripts/docker/cmd.sh | 7 - dev-scripts/docker/composer.phar | Bin 1852323 -> 0 bytes dev-scripts/docker/find-addons2.sh | 10 - dev-scripts/docker/ssl-cert-snakeoil.key | 28 -- dev-scripts/docker/ssl-cert-snakeoil.pem | 17 - docker-compose.yml | 59 +-- {dev-scripts/docker => docker}/build.sh | 0 .../docker => docker}/cmd-php--xf-addon.sh | 0 {dev-scripts/docker => docker}/cmd-php.sh | 0 {dev-scripts/docker => docker}/phpcs.xml | 0 .../docker => docker}/xf-addon--create.sh | 0 .../docker => docker}/xf-addon--export.sh | 0 .../docker => docker}/xf-addon--phpcbf.sh | 0 .../docker => docker}/xf-addon--phpcs.sh | 0 .../xf-dev--export--addon.sh | 0 router.php | 12 - src/addons/DevHelper/.gitignore | 3 - src/addons/DevHelper/Autoloader.php | 85 ---- src/addons/DevHelper/DevHelper/Hint/XF.php | 9 - src/addons/DevHelper/Listener.php | 16 - src/addons/DevHelper/Router.php | 222 ---------- src/addons/DevHelper/StreamWrapper.php | 387 ------------------ src/addons/DevHelper/XF/AddOn/AddOn.php | 29 -- src/addons/DevHelper/XF/AddOn/Manager.php | 29 -- src/addons/DevHelper/XF/Extension.php | 49 --- .../XF/Service/AddOn/ReleaseBuilder.php | 33 -- src/addons/DevHelper/XF/XF.php | 11 - xenforo/.gitkeep | 0 35 files changed, 24 insertions(+), 1170 deletions(-) mode change 100755 => 100644 .gitignore delete mode 100644 .htaccess create mode 100644 Dockerfile delete mode 100644 README.md delete mode 100644 addons/.gitkeep delete mode 100644 cmd.php delete mode 100644 dev-scripts/Dockerfile.php-apache delete mode 100644 dev-scripts/docker/cmd.sh delete mode 100755 dev-scripts/docker/composer.phar delete mode 100644 dev-scripts/docker/find-addons2.sh delete mode 100644 dev-scripts/docker/ssl-cert-snakeoil.key delete mode 100644 dev-scripts/docker/ssl-cert-snakeoil.pem rename {dev-scripts/docker => docker}/build.sh (100%) rename {dev-scripts/docker => docker}/cmd-php--xf-addon.sh (100%) rename {dev-scripts/docker => docker}/cmd-php.sh (100%) rename {dev-scripts/docker => docker}/phpcs.xml (100%) rename {dev-scripts/docker => docker}/xf-addon--create.sh (100%) rename {dev-scripts/docker => docker}/xf-addon--export.sh (100%) rename {dev-scripts/docker => docker}/xf-addon--phpcbf.sh (100%) rename {dev-scripts/docker => docker}/xf-addon--phpcs.sh (100%) rename {dev-scripts/docker => docker}/xf-dev--export--addon.sh (100%) delete mode 100644 router.php delete mode 100644 src/addons/DevHelper/.gitignore delete mode 100644 src/addons/DevHelper/Autoloader.php delete mode 100644 src/addons/DevHelper/DevHelper/Hint/XF.php delete mode 100644 src/addons/DevHelper/Listener.php delete mode 100644 src/addons/DevHelper/Router.php delete mode 100644 src/addons/DevHelper/StreamWrapper.php delete mode 100644 src/addons/DevHelper/XF/AddOn/AddOn.php delete mode 100644 src/addons/DevHelper/XF/AddOn/Manager.php delete mode 100644 src/addons/DevHelper/XF/Extension.php delete mode 100644 src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php delete mode 100644 src/addons/DevHelper/XF/XF.php delete mode 100644 xenforo/.gitkeep diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index e69de29..806a90c --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/.data/ diff --git a/.htaccess b/.htaccess deleted file mode 100644 index f9b3625..0000000 --- a/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -RewriteEngine On -RewriteRule ^.*$ router.php [NC,L] \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9d0df12 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM xfrocks/xenforo:php-apache-7.2.3 + +COPY docker/* /usr/local/bin/ +RUN chmod +x /usr/local/bin/*.sh + +RUN /usr/local/bin/build.sh + +WORKDIR "/var/www/html/src/addons" diff --git a/README.md b/README.md deleted file mode 100644 index 8feb9a7..0000000 --- a/README.md +++ /dev/null @@ -1,162 +0,0 @@ -# XenForo Developer Helper add-on - -## Installation -### The Easy Way -Just copy files and import the xml file as usual. - -If you want to help developing this add-on. It's recommended to clone the repo elsewhere then create symbolic links for `js/DevHelper` and `library/DevHelper`. -### Advanced Installation -Edit XenForo `index.php` and `admin.php` files in root directory. Look for these lines: - -``` -require($fileDir . '/library/XenForo/Autoloader.php'); -XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library'); -``` - -Replace them with: - -``` -require($fileDir . '/library/XenForo/Autoloader.php'); -require($fileDir . '/library/DevHelper/Autoloader.php'); -DevHelper_Autoloader::getDevHelperInstance()->setupAutoloader($fileDir . '/library'); -``` -This is required to use features like ShippableHelper injection, debug information in AJAX requests, etc. - -## Features - * Quickly setup add-on environment (UNIX only) with command line `xf-new-addon addOnId path/to/xenforo/root`. This will create a new directory `addOnId` in the current directory with the below layout. All inner `addOnId` directories will be symlink'd to their places within `path/to/xenforo/root` making it easy for you to start coding. All files should be put within one of these 3 directories. - -``` -addOnId - | - |--repo - | - |--js - | - |--addOnId - |--library - | - |--addOnId - |--styles - | - |--default - | - |--addOnId -``` - - * __Data Manager__ with flexible configuration. It can generates DataWriter, Model, Route PrefixAdmin, ControllerAdmin for you. See __Configuration__ for detailed information. - * __Generate Installer___ (and uninstaller too) using data from __Data Manager__. - * __File Export__ to copy clean files from working directory to another directory for easy package. Added benefits include: - * Auto generated `FileSums.php` - * Phrase check (unused phrases, deleted phrases, phrases from other add-ons) - * Auto generated `XFCP` classes for better IDE support (class hint, method hint, etc.) - *. Template editors - -## Configuration -The first time you visit __Data Manager__ for an add-on, a new file will be generated in `library/addOnId/DevHelper/Config.php` and it looks like this: - -``` -addDataPatch( - 'xf_user', - array( - 'name' => 'money', - 'type' => 'uint', - 'default' => 0, - ) - ); - } -} -``` - -When the `Config` file is upgraded, it will look like this: - -``` - array( - 'addonid_money' => array('name' => 'addonid_money', 'type' => 'uint', 'default' => 0), - ), - ); - - protected function _upgrade() - { - return true; // remove this line to trigger update - } -} -``` - -And if you generate installer from the AdminCP, you will get this `Installer` file: - -``` - 'xf_user', - 'field' => 'addonid_money', - 'showTablesQuery' => 'SHOW TABLES LIKE \'xf_user\'', - 'showColumnsQuery' => 'SHOW COLUMNS FROM `xf_user` LIKE \'addonid_money\'', - 'alterTableAddColumnQuery' => 'ALTER TABLE `xf_user` ADD COLUMN `addonid_money` INT(10) UNSIGNED DEFAULT \'0\'', - 'alterTableDropColumnQuery' => 'ALTER TABLE `xf_user` DROP COLUMN `addonid_money`', - ), - ); - - public static function install($existingAddOn, $addOnData) - { - $db = XenForo_Application::get('db'); - - foreach (self::$_patches as $patch) { - $tableExisted = $db->fetchOne($patch['showTablesQuery']); - if (empty($tableExisted)) { - continue; - } - - $existed = $db->fetchOne($patch['showColumnsQuery']); - if (empty($existed)) { - $db->query($patch['alterTableAddColumnQuery']); - } - } - } - - public static function uninstall() - { - $db = XenForo_Application::get('db'); - - foreach (self::$_patches as $patch) { - $tableExisted = $db->fetchOne($patch['showTablesQuery']); - if (empty($tableExisted)) { - continue; - } - - $existed = $db->fetchOne($patch['showColumnsQuery']); - if (!empty($existed)) { - $db->query($patch['alterTableDropColumnQuery']); - } - } - } -} -``` \ No newline at end of file diff --git a/addons/.gitkeep b/addons/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/cmd.php b/cmd.php deleted file mode 100644 index 7478b65..0000000 --- a/cmd.php +++ /dev/null @@ -1,4 +0,0 @@ -?5=Dp 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 z

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≧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ⅈ+uu6?hhryz`hx1-6E8^hu#QTte?Cf6ZN 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�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%0D}p%Hh{e#zU+^n?Yl_1L0!#ZC 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›xQX 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

-pdcH8?i*q0*|&2>G#cg7TyQsvsEGqkIRp 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 ./xenforo/internal_data/addons2.txt diff --git a/dev-scripts/docker/ssl-cert-snakeoil.key b/dev-scripts/docker/ssl-cert-snakeoil.key deleted file mode 100644 index d64eda6..0000000 --- a/dev-scripts/docker/ssl-cert-snakeoil.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCuLUoflUrEZWbb -2E4vEItF51ho9jjYSaXd7q0Q5yuQvw0vF3a5Ucm9bIWkxJMKBvznWRut+1yKB8kM -Yi9z+vHpw+A814Mr91WVcwEaH4VdpPAY6iyH3/wfu61poeVifnN5yH02Z/CkC6c0 -/UR9yrE9nGLZ883LTMhPYo/8YoAgFdzZ82aMoMf7ZH8WU3YyWMrvc98hQxsbqcMu -djXv1301FY9U/S9ybUaJnoRCWOgLGP4IU9rWOfOEs9PtJpax55i3WDTjEPIlvfFq -bpQAUQDx8+9ZpSpma1iRLx8vytZdTiLxOORIeoYpqWINxNoj6MIGetMMKSKCn1Lu -kTWqs1qhAgMBAAECggEAOUB9yt/h0aibJMx29pVzkii3MNkuWjnrIYYgsRurgEqs -ZLxLtCKkM3WGgGB1DKi7XLg3lvq2slBYz48+ldr4xaQzAwy7+ymzogpJZHLT/bIH -kcj3ljoTv8KK/9vNcJCsGG3EaqvDt8h0z8AoUUjc9al//LBdBuRYO2/kcEtYXjMG -UOOJdX1n/HDsS3gLnC+TN2m1NFXdt9//AO4lCdbkdAPhc90h44nKOSXl4nZZe3uw -GNUSmKkY57YZd84Ybyca2DX6hkpBWNSIBbMyU2c2k1Ka5RjVhEVYgyNiCvGsA8Fa -gGat1KJerS9wOcBRub6qY8mMxtFztgSST8uZGRbcIQKBgQDjTw254uXeK0Xt3Ml3 -Vs7IZUdJK6fP1NFN8lsFCchsZ9aUD+S4zw5o0WBsF8TS399SeczrmhVy3MiLEd4C -SDTVCMikj2A+VTs7v1ZpqyADh+9xybFq1NOx2dnyB6ochFVAeeEAqE+Pcy6cVmow -p4/P/9R+tiGshn2mQXPzfzVUBQKBgQDEKWePUlm12+W05SkI9L4LTFgGhZnwTDhr -t35ZeFM0Ih2qcIkf2t8eVRtVgYqBSg/F4o4efOmoyif5C96Y9h9PicJGYglcDUkc -XXSGkUHjjHdnZAhxSgSjyXf1QGvwVFtfy5XNAdOB5pVsN6UPhNoAYE0xzCapTiZg -ZuHgZ+jq7QKBgE/iYHiLfS1vF8xYY5VFNLbIoRzd8sPfjw9NtR84KO+wLoEqdL9e -RTohGznhwJI7i0h49cN3C0KqxO/a/6LdrXOQ+rKakMBXQ9HjlILeWQnkpAnhUDCz -SxKd9TJR7z7GYw+dxa1teUh4ulDHLdqbiLcYuZ0udPck7NOY/R79/cfhAoGACnkX -cVx5M69w3S6a+UJv3xSNYpPBe0XmgUHDui0lbBQiN1ZYy92YqfrrQa5v4aU9oFgP -NGuA4iUg6zgKA2qok0uMlstnKoX/EEehEAozVV3LhjaeCMZl5wS7pdlxqdwnIL8y -2UYur7HK6oMyCdkS9pAtrunyanmkrOLxTlTd56UCgYA4qSWFyCj4HhMc/IVUfQO3 -qsqu+2gsNJefR+Wk9iwoNFPWcHHX8SEBT6fa+Yl18OVTbaEtB2Oit+69Snu8/dKA -icsNheL/djmy2iAd4fDdNmgcZtg5t1Aiu4GmDMZzcydz1O255wxx0Qo+Sb2/ReV9 -Wsdg1FBo2W4107vFpQokNw== ------END PRIVATE KEY----- diff --git a/dev-scripts/docker/ssl-cert-snakeoil.pem b/dev-scripts/docker/ssl-cert-snakeoil.pem deleted file mode 100644 index c05f2e6..0000000 --- a/dev-scripts/docker/ssl-cert-snakeoil.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICvjCCAaagAwIBAgIJAL2kworg9DfqMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV -BAMMDGFmMjUzYjViOWFmODAeFw0xNzEwMzAwMzU2MTRaFw0yNzEwMjgwMzU2MTRa -MBcxFTATBgNVBAMMDGFmMjUzYjViOWFmODCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAK4tSh+VSsRlZtvYTi8Qi0XnWGj2ONhJpd3urRDnK5C/DS8XdrlR -yb1shaTEkwoG/OdZG637XIoHyQxiL3P68enD4DzXgyv3VZVzARofhV2k8BjqLIff -/B+7rWmh5WJ+c3nIfTZn8KQLpzT9RH3KsT2cYtnzzctMyE9ij/xigCAV3NnzZoyg -x/tkfxZTdjJYyu9z3yFDGxupwy52Ne/XfTUVj1T9L3JtRomehEJY6AsY/ghT2tY5 -84Sz0+0mlrHnmLdYNOMQ8iW98WpulABRAPHz71mlKmZrWJEvHy/K1l1OIvE45Eh6 -himpYg3E2iPowgZ60wwpIoKfUu6RNaqzWqECAwEAAaMNMAswCQYDVR0TBAIwADAN -BgkqhkiG9w0BAQsFAAOCAQEAVPMo4zeyMy3Sky+pmrxAc6ORIRpG0eKDw+8Uo+Vn -nrzJ/wChyJbJ3tpIX2CWn3BvA2T/DHuCr4FTcBQHWWo6alhWagAnQ5i+RMVPP+8A -6ZES46lhRX3jxngkQ4iuQCeOtT/1qpvHmp4U1jZ3mGoopEvbMd7kn1ByS7DxsFxQ -RMEw1JvjSESzncnQJ0CoyxCqMd5UE749jcitvHNEhI5SU4smjdwy60NHP2xgBfxf -YebDtYQkIrp/6usr+1E+wGw1WkoJyoBrIlX7Mfgzv2R3UEiMJ3oEqu1F6tgs6AQo -Qg+2fXkrqtySheVEg0ebKTambjbzWxv5VCUo74q56rDKMw== ------END CERTIFICATE----- diff --git a/docker-compose.yml b/docker-compose.yml index 4edfd67..a069329 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,55 +1,26 @@ version: '2' services: - php-apache: + php: build: - context: dev-scripts - dockerfile: Dockerfile.php-apache - environment: - - VIRTUAL_HOST=xenforo.local.xfrocks.com - expose: - - "80" - links: - - mysqld:mysqld - #volumes: - #- /path/to/xenforo:/var/www/html/xenforo:rw - #- /path/to/addons:/var/www/html/addons:rw - #- .:/var/www/html/:rw - - php-cli: - image: xfrocks/docker-xenforo:php-cli + context: . links: - - php-apache:php-apache - - mysqld:mysqld - volumes_from: - - php-apache - working_dir: /var/www/html/ + - mysql:mysql + ports: + - "80:80" + volumes: + - ./../../xenforo:/var/www/html + - ./..:/var/www/html/src/addons + - ./../../xenforo/src/addons/XF:/var/www/html/src/addons/XF + - ./.data/external:/var/www/html/data + - ./.data/internal:/var/www/html/internal_data - mysqld: + mysql: image: mysql:latest environment: - MYSQL_RANDOM_ROOT_PASSWORD: 'yes' - MYSQL_ONETIME_PASSWORD: 'yes' - MYSQL_DATABASE: 'xenforo' - MYSQL_USER: 'xenforo' - MYSQL_PASSWORD: 'xenforo' + MYSQL_DATABASE: 'xenforo2' + MYSQL_ROOT_PASSWORD: 'root' expose: - "3306" volumes: - - ./.data/mysql:/var/lib/mysql:rw - - mysql: - image: arey/mysql-client - links: - - mysqld:mysqld - volumes_from: - - php-apache - working_dir: /var/www/html/ - entrypoint: mysql -hmysqld -uxenforo -pxenforo xenforo - - nginx-proxy: - image: jwilder/nginx-proxy - ports: - - "80:80" - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro \ No newline at end of file + - ./.data/mysql:/var/lib/mysql diff --git a/dev-scripts/docker/build.sh b/docker/build.sh similarity index 100% rename from dev-scripts/docker/build.sh rename to docker/build.sh diff --git a/dev-scripts/docker/cmd-php--xf-addon.sh b/docker/cmd-php--xf-addon.sh similarity index 100% rename from dev-scripts/docker/cmd-php--xf-addon.sh rename to docker/cmd-php--xf-addon.sh diff --git a/dev-scripts/docker/cmd-php.sh b/docker/cmd-php.sh similarity index 100% rename from dev-scripts/docker/cmd-php.sh rename to docker/cmd-php.sh diff --git a/dev-scripts/docker/phpcs.xml b/docker/phpcs.xml similarity index 100% rename from dev-scripts/docker/phpcs.xml rename to docker/phpcs.xml diff --git a/dev-scripts/docker/xf-addon--create.sh b/docker/xf-addon--create.sh similarity index 100% rename from dev-scripts/docker/xf-addon--create.sh rename to docker/xf-addon--create.sh diff --git a/dev-scripts/docker/xf-addon--export.sh b/docker/xf-addon--export.sh similarity index 100% rename from dev-scripts/docker/xf-addon--export.sh rename to docker/xf-addon--export.sh diff --git a/dev-scripts/docker/xf-addon--phpcbf.sh b/docker/xf-addon--phpcbf.sh similarity index 100% rename from dev-scripts/docker/xf-addon--phpcbf.sh rename to docker/xf-addon--phpcbf.sh diff --git a/dev-scripts/docker/xf-addon--phpcs.sh b/docker/xf-addon--phpcs.sh similarity index 100% rename from dev-scripts/docker/xf-addon--phpcs.sh rename to docker/xf-addon--phpcs.sh diff --git a/dev-scripts/docker/xf-dev--export--addon.sh b/docker/xf-dev--export--addon.sh similarity index 100% rename from dev-scripts/docker/xf-dev--export--addon.sh rename to docker/xf-dev--export--addon.sh diff --git a/router.php b/router.php deleted file mode 100644 index 37dcec1..0000000 --- a/router.php +++ /dev/null @@ -1,12 +0,0 @@ -_setup) { - return; - } - - /** @var \Composer\Autoload\ClassLoader $autoLoader */ - /** @noinspection PhpIncludeInspection */ - $autoLoader = require('/var/www/html/xenforo/src/vendor/autoload.php'); - - $autoLoader->setPsr4('DevHelper\\', __DIR__); - - list(, $addOnPaths) = Router::getLocatePaths(); - foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { - $globPattern = $addOnPath . '/src/addons/*'; - $rootPaths = glob($globPattern); - foreach ($rootPaths as $rootPath) { - $rootNamespace = basename($rootPath); - $autoLoader->setPsr4($rootNamespace . '\\', $rootPath); - } - - if (count($rootPaths) === 0) { - $rootNamespace = str_replace(DIRECTORY_SEPARATOR, '\\', $addOnPathSuffix); - $autoLoader->setPsr4($rootNamespace . '\\', $addOnPath); - } - } - - spl_autoload_register(array($this, 'autoload'), true, true); - - $this->_setup = true; - } - - public function autoload($class) - { - if (class_exists($class, false) || interface_exists($class, false)) { - return true; - } - - if ($class == 'utf8_entity_decoder') { - return false; - } - - if (substr($class, 0, 5) == 'XFCP_') { - return false; - } - - file_put_contents('/var/www/html/xenforo/internal_data/autoload.log', $class . "\n", FILE_APPEND); - switch ($class) { - case 'XF\Extension': - $original = file_get_contents('/var/www/html/xenforo/src/XF/Extension.php'); - $renamed = str_replace('class Extension', 'class _Extension', $original); - eval(substr($renamed, strlen('setDefaultOption('verify', '/var/www/html/xenforo/src/XF/Http/ca-bundle.crt'); - } -} \ No newline at end of file diff --git a/src/addons/DevHelper/Router.php b/src/addons/DevHelper/Router.php deleted file mode 100644 index 64a44e3..0000000 --- a/src/addons/DevHelper/Router.php +++ /dev/null @@ -1,222 +0,0 @@ -setupAutoloader(); - } - - public static function locateCached($fullPath) - { - $key = basename($fullPath) . md5($fullPath); - $cached = apcu_fetch($key); - $located = null; - $success = false; - if (is_array($cached) - && $cached['fullPath'] === $fullPath) { - $located = $cached['located']; - } - - if (empty($located)) { - $located = static::locate($fullPath, $success); - } - - if ($success) { - $cacheEntry = array( - 'fullPath' => $fullPath, - 'located' => $located, - ); - - apcu_store($key, $cacheEntry); - } - - return $located; - } - - public static function locate($fullPath, &$success = null) - { - if (file_exists($fullPath)) { - $success = true; - return $fullPath; - } - - list($xenforoDir, $addOnPaths) = static::getLocatePaths(); - $shortened = preg_replace( - '#^' . preg_quote($xenforoDir, '#') . '#', - '', - $fullPath - ); - - $srcAddOnsPath = null; - if (strpos($shortened, static::PATH_SLASH_SRC_ADDONS_SLASH) === 0) { - $srcAddOnsPath = substr($shortened, strlen(static::PATH_SLASH_SRC_ADDONS_SLASH)); - } - - foreach ($addOnPaths as $addOnPathSuffix => $addOnPath) { - $candidatePaths = []; - - if ($srcAddOnsPath !== null) { - if (strpos($srcAddOnsPath, $addOnPathSuffix) === 0) { - $candidatePaths[] = $addOnPath . '/' . substr($srcAddOnsPath, strlen($addOnPathSuffix)); - } elseif (strpos($addOnPathSuffix, $srcAddOnsPath) === 0) { - $parentPathSuffix = dirname($addOnPathSuffix); - $parentPath = dirname($addOnPath); - if (strpos($srcAddOnsPath, $parentPathSuffix) === 0) { - $candidatePaths[] = $parentPath; - } - } - } else { - // for non-PHP files, we support 2 types of add-on files structure - $fullSuffix = '/src/addons/' . $addOnPathSuffix; - if (substr($addOnPath, -strlen($fullSuffix)) === $fullSuffix) { - // `full` type has js files in addons/AddOnId/js/ - // and `addon.json` is at addons/AddOnId/src/addons/AddOnId/addon.json - $candidatePaths[] = substr($addOnPath, 0, -strlen($fullSuffix)) . $shortened; - } else { - // `repo` type has js files in addons/AddOnId/_files/js/ - // and `addon.json` is at addons/AddOnId/addon.json - $candidatePaths[] = $addOnPath . '/_files' . $shortened; - } - } - - foreach ($candidatePaths as $candidatePath) { - if (file_exists($candidatePath)) { - $success = true; - return $candidatePath; - } - } - } - - if (!$success && $srcAddOnsPath !== null) { - $candidatePath = '/var/www/html/addons/' . $srcAddOnsPath; - if (file_exists($candidatePath)) { - $success = true; - return $candidatePath; - } - } - - return $fullPath; - } - - public static function getLocatePaths() - { - static $xenforoDir = null; - static $addOnPaths = null; - static $addonsDir = null; - - if ($addOnPaths === null) { - $routerPhp = $_SERVER['DEVHELPER_ROUTER_PHP']; - $routerPhpDir = dirname($routerPhp); - $xenforoDir = sprintf('%s/xenforo', $routerPhpDir); - $addonsDir = sprintf('%s/addons', $routerPhpDir); - $addOnPaths = array(); - - $txtPath = sprintf('%s/internal_data/addons2.txt', $xenforoDir); - if (!file_exists($txtPath)) { - exec('/usr/local/bin/find-addons2.sh'); - } - $lines = file($txtPath); - $prefix = 'addons'; - $prefixLength = strlen($prefix); - - foreach ($lines as $line) { - $line = trim($line); - if (strlen($line) === 0) { - continue; - } - - if (substr($line, 0, $prefixLength) !== $prefix) { - continue; - } - - $lineWithoutAddOnJson = preg_replace('#/addon.json$#', '', $line, -1, $count); - if ($count !== 1) { - continue; - } - - $addOnPath = sprintf('%s/%s', $routerPhpDir, $lineWithoutAddOnJson); - $addOnPathSuffix = trim(preg_replace('#^.+addons#', '', $addOnPath), '/'); - $addOnPaths[$addOnPathSuffix] = $addOnPath; - } - } - - return array($xenforoDir, $addOnPaths, $addonsDir); - } - - public static function locateReset() - { - apcu_clear_cache(); - exec('/usr/local/bin/find-addons2.sh'); - } -} diff --git a/src/addons/DevHelper/StreamWrapper.php b/src/addons/DevHelper/StreamWrapper.php deleted file mode 100644 index ec7b012..0000000 --- a/src/addons/DevHelper/StreamWrapper.php +++ /dev/null @@ -1,387 +0,0 @@ -_dirHandle)) { - return false; - } - - closedir($this->_dirHandle); - - if (!empty($this->_dirSecondHandle)) { - closedir($this->_dirSecondHandle); - } - - $this->_dirPath = null; - $this->_dirHandle = null; - $this->_dirSecondHandle = null; - - return true; - } - - /** - * Open directory handle - * - * @param string $path - * @param int $options - * @return bool - */ - public function dir_opendir($path, $options) - { - $located = static::locate($path); - if (!file_exists($located)) { - return false; - } - - $this->_dirPath = $path; - $this->_dirHandle = opendir($located); - - if ($located === '/var/www/html/xenforo/src/addons') { - $this->_dirSecondHandle = opendir('/var/www/html/addons'); - } - - return true; - } - - /** - * Read entry from directory handle - * - * @return string|false - */ - public function dir_readdir() - { - if (empty($this->_dirHandle)) { - return false; - } - - $read = readdir($this->_dirHandle); - - if ($read === false && !empty($this->_dirSecondHandle)) { - while (true) { - $secondRead = readdir($this->_dirSecondHandle); - switch ($secondRead) { - case '.': - case '..': - continue; - } - - return $secondRead; - } - } - - return $read; - } - - /** - * Rewind directory handle - * - * @return bool - */ - public function dir_rewinddir() - { - if (empty($this->_dirHandle)) { - return false; - } - - $bool = rewinddir($this->_dirHandle); - - if (!empty($this->_dirSecondHandle)) { - rewind($this->_dirSecondHandle); - } - - return $bool; - } - - /** - * Create a directory - * - * @param string $path - * @param int $mode - * @param int $options - * @return bool - */ - public function mkdir($path, $mode, $options) - { - $located = static::locate($path); - if (!file_exists($located)) { - list($xenforoDir, , $addonsDir) = Router::getLocatePaths(); - $locatedDir = static::locate(dirname($path)); - if ($locatedDir === $xenforoDir . '/src/addons') { - $located = $addonsDir . DIRECTORY_SEPARATOR . basename($path); - } elseif (is_dir($locatedDir)) { - $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); - } - } - - return mkdir($located, $mode, $options); - } - - /** - * @param string $path - * @param int $options - * @return bool - */ - public function rmdir($path, $options) - { - $located = static::locate($path); - if (!file_exists($located)) { - return false; - } - - return rmdir($located); - } - - /** - * Retrieve the under laying resource - * - * @param int $castAs - * @return resource - */ - public function stream_cast($castAs) - { - if (empty($this->_streamHandle)) { - return null; - } - - return $this->_streamHandle; - } - - /** - * Close an resource - */ - public function stream_close() - { - if (empty($this->_streamHandle)) { - return; - } - - fclose($this->_streamHandle); - - if (basename($this->_streamPath) === 'addon.json' && $this->_streamWritten > 0) { - Router::locateReset(); - } - - $this->_streamPath = null; - $this->_streamHandle = null; - $this->_streamWritten = null; - } - - /** - * Tests for end-of-file on a file pointer - * - * @return bool - */ - public function stream_eof() - { - if (empty($this->_streamHandle)) { - return true; - } - - return feof($this->_streamHandle); - } - - /** - * Advisory file locking - * - * @param $operation - * @return bool - */ - public function stream_lock($operation) - { - if (empty($this->_streamHandle)) { - return false; - } - - return flock($this->_streamHandle, $operation); - } - - /** - * Change stream metadata - * - * @param string $path - * @param int $option - * @param mixed $value - * @return bool - */ - public function stream_metadata($path, $option, $value) - { - switch ($option) { - case STREAM_META_ACCESS: - $located = static::locate($path); - return chmod($located, $value); - } - - return false; - } - - /** - * Opens file or URL - * - * @param string $path - * @param string $mode - * @param int $options - * @param string &$openedPath - * @return bool - */ - public function stream_open($path, $mode, $options, &$openedPath) - { - $needCreate = false; - if (strpos($mode, 'c') !== false) { - // modes: c, c+ - $needCreate = true; - } elseif (strpos($mode, 'a') !== false - || strpos($mode, '+') !== false - ) { - // modes: r+, w+, a, a+, x+ - $needCreate = true; - } elseif (strpos($mode, 'w') !== false - || strpos($mode, 'x') !== false - ) { - // modes: w, x - $needCreate = true; - } - - $located = static::locate($path); - if ($needCreate && !file_exists($located)) { - $locatedDir = static::locate(dirname($path)); - if (is_dir($locatedDir)) { - $located = $locatedDir . DIRECTORY_SEPARATOR . basename($path); - } - } - - $this->_streamPath = $path; - $this->_streamHandle = fopen($located, $mode); - $this->_streamWritten = 0; - - return true; - } - - /** - * Read from stream - * - * @param int $count - * @return string - */ - public function stream_read($count) - { - if (empty($this->_streamHandle)) { - return ''; - } - - return fread($this->_streamHandle, $count); - } - - public function stream_seek($offset, $whence = SEEK_SET) - { - if (empty($this->_streamHandle)) { - return false; - } - - return fseek($this->_streamHandle, $offset, $whence); - } - - /** - * Retrieve information about a file resource - * - * @return array|false - */ - public function stream_stat() - { - if (empty($this->_streamHandle)) { - return false; - } - - return fstat($this->_streamHandle); - } - - /** - * Write to stream - * - * @param string $data - * @return int - */ - public function stream_write($data) - { - if (empty($this->_streamHandle)) { - return 0; - } - - $written = fwrite($this->_streamHandle, $data); - $this->_streamWritten += $written; - - return $written; - } - - /** - * Delete a file - * - * @param string $path - * @return bool - */ - public function unlink($path) - { - $located = static::locate($path); - if (!file_exists($located)) { - return false; - } - - return unlink($located); - } - - /** - * Retrieve information about a file - * - * @param string $path - * @param int $flags - * @return array|false - */ - public function url_stat($path, $flags) - { - $located = static::locate($path); - - if (!file_exists($located)) { - return false; - } - - $stat = stat($located); - - return $stat; - } - - /** - * @param string $path - * @return string - * @throws \Exception - */ - public static function locate($path) - { - $protocolLength = strlen(static::PROTOCOL); - if (substr($path, 0, $protocolLength) !== static::PROTOCOL) { - throw new \Exception('Unrecognized path ' . $path); - } - - $pathWithoutProtocol = substr($path, $protocolLength + 3); - list($xenforoDir) = Router::getLocatePaths(); - $pathFromRoot = $xenforoDir . DIRECTORY_SEPARATOR . $pathWithoutProtocol; - - return Router::locateCached($pathFromRoot); - } -} \ No newline at end of file diff --git a/src/addons/DevHelper/XF/AddOn/AddOn.php b/src/addons/DevHelper/XF/AddOn/AddOn.php deleted file mode 100644 index 6631d77..0000000 --- a/src/addons/DevHelper/XF/AddOn/AddOn.php +++ /dev/null @@ -1,29 +0,0 @@ -prepareAddOnIdForFilename(); - $versionString = $this->prepareVersionForFilename(); - /** @noinspection PhpUndefinedFieldInspection */ - $this->buildDir = '/var/www/html/xenforo/internal_data/builds/' . $addOnId . '/' . $versionString; - /** @noinspection PhpUndefinedFieldInspection */ - $this->releasesDir = '/var/www/html/xenforo/internal_data/releases/' . $addOnId; - } - - public function passesHealthCheck(&$missing = [], &$inconsistent = []) - { - return; - } -} - -if (false) { - class XFCP_AddOn extends \XF\AddOn\AddOn - { - } -} diff --git a/src/addons/DevHelper/XF/AddOn/Manager.php b/src/addons/DevHelper/XF/AddOn/Manager.php deleted file mode 100644 index cdaa154..0000000 --- a/src/addons/DevHelper/XF/AddOn/Manager.php +++ /dev/null @@ -1,29 +0,0 @@ -extendClass('XF\AddOn\AddOn'); - - return new $class($addOnOrId ?: $addOn->getAddOnId()); - } -} - -if (false) { - class XFCP_Manager extends \XF\AddOn\Manager - { - } -} diff --git a/src/addons/DevHelper/XF/Extension.php b/src/addons/DevHelper/XF/Extension.php deleted file mode 100644 index 0a199c8..0000000 --- a/src/addons/DevHelper/XF/Extension.php +++ /dev/null @@ -1,49 +0,0 @@ -initDevHelper(); - } - - private function initDevHelper() - { - static $initOk = false; - if ($initOk) { - return; - } - $initOk = true; - - require(dirname(__DIR__) . '/StreamWrapper.php'); - stream_wrapper_register(StreamWrapper::PROTOCOL, StreamWrapper::class); - XF::setSourceDirectory(StreamWrapper::PROTOCOL . '://src'); - - $this->addListener('http_client_config', ['DevHelper\\Listener', 'httpClientConfig']); - - $classes = [ - 'XF\AddOn\AddOn', - 'XF\AddOn\Manager', - 'XF\Service\AddOn\ReleaseBuilder', - ]; - foreach ($classes as $class) { - $this->addClassExtension($class, 'DevHelper\\' . $class); - } - } -} diff --git a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php b/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php deleted file mode 100644 index 671869b..0000000 --- a/src/addons/DevHelper/XF/Service/AddOn/ReleaseBuilder.php +++ /dev/null @@ -1,33 +0,0 @@ -buildRoot . '/oops'; - File::createDirectory($oopsPath, false); - $this->buildRoot = $oopsPath; - - parent::finalizeRelease(); - } - - protected function getExcludedDirectories() - { - $dirs = parent::getExcludedDirectories(); - - $dirs[] = '.git'; - - return $dirs; - } -} - -if (false) { - class XFCP_ReleaseBuilder extends \XF\Service\AddOn\ReleaseBuilder - { - } -} \ No newline at end of file diff --git a/src/addons/DevHelper/XF/XF.php b/src/addons/DevHelper/XF/XF.php deleted file mode 100644 index 76c30eb..0000000 --- a/src/addons/DevHelper/XF/XF.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Sat, 14 Apr 2018 09:57:57 +0700 Subject: [PATCH 029/118] php 7.2.4 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9d0df12..9cc7abe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM xfrocks/xenforo:php-apache-7.2.3 +FROM xfrocks/xenforo:php-apache-7.2.4 COPY docker/* /usr/local/bin/ RUN chmod +x /usr/local/bin/*.sh From c65c09580979d8edd4337c50434836754d429dec Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Sat, 14 Apr 2018 10:09:49 +0700 Subject: [PATCH 030/118] Fix DEVHELPER_PHP_APACHE_VERSION_ID unused reference --- docker/build.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/docker/build.sh b/docker/build.sh index 837d5ad..74c860e 100644 --- a/docker/build.sh +++ b/docker/build.sh @@ -2,7 +2,6 @@ set -e -echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-available/env.conf a2enmod env rewrite for _verb in build-release \ From 1aaf9db8de87005e638ce9f5592980adc53f2282 Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 17 Apr 2018 11:30:42 +0700 Subject: [PATCH 031/118] Initial support for Autogen/Admin/Controller/Entity.php --- .dockerignore | 2 + .gitignore | 1 + Autogen/Admin/Controller/Entity.php | 532 ++++++++++++++++++++++++++++ Cli/Command/AutoGen.php | 129 +++++++ _data/templates.xml | 108 ++++++ addon.json | 14 + docker/devhelper-autogen.sh | 5 + 7 files changed, 791 insertions(+) create mode 100644 .dockerignore create mode 100644 Autogen/Admin/Controller/Entity.php create mode 100644 Cli/Command/AutoGen.php create mode 100644 _data/templates.xml create mode 100644 addon.json create mode 100644 docker/devhelper-autogen.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..41d3411 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +/.data/ +/_output/ diff --git a/.gitignore b/.gitignore index 806a90c..41d3411 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.data/ +/_output/ diff --git a/Autogen/Admin/Controller/Entity.php b/Autogen/Admin/Controller/Entity.php new file mode 100644 index 0000000..e77cb98 --- /dev/null +++ b/Autogen/Admin/Controller/Entity.php @@ -0,0 +1,532 @@ +filterPage(); + $perPage = $this->getPerPage(); + + $finder = $this->em()->getFinder($this->getShortName())->limitByPage($page, $perPage); + $total = $finder->total(); + + $viewParams = [ + 'entities' => $finder->fetch(), + + 'page' => $page, + 'perPage' => $perPage, + 'total' => $total + ]; + + return $this->getViewReply('list', $viewParams); + } + + /** + * @return View + */ + public function actionAdd() + { + if (!$this->supportsAdding()) { + return $this->noPermission(); + } + + return $this->entityAddEdit($this->createEntity()); + } + + /** + * @param ParameterBag $params + * @return View|Redirect + * @throws \XF\Mvc\Reply\Exception + * @throws \XF\PrintableException + */ + public function actionDelete(ParameterBag $params) + { + if (!$this->supportsDeleting()) { + return $this->noPermission(); + } + + $entityId = $this->getEntityIdFromParams($params); + $entity = $this->assertEntityExists($entityId); + + if ($this->isPost()) { + $entity->delete(); + + return $this->redirect($this->buildLink($this->getRoutePrefix())); + } + + /** @noinspection PhpUndefinedMethodInspection */ + $entityLabel = $entity->getLabel(); + + $viewParams = [ + 'entity' => $entity, + 'entityLabel' => $entityLabel + ]; + + return $this->getViewReply('delete', $viewParams); + } + + /** + * @param ParameterBag $params + * @return \XF\Mvc\Reply\View + * @throws \XF\Mvc\Reply\Exception + */ + public function actionEdit(ParameterBag $params) + { + if (!$this->supportsEditing()) { + return $this->noPermission(); + } + + $entityId = $this->getEntityIdFromParams($params); + $entity = $this->assertEntityExists($entityId); + return $this->entityAddEdit($entity); + } + + /** + * @return \XF\Mvc\Reply\Error|\XF\Mvc\Reply\Redirect + * @throws \Exception + * @throws \XF\Mvc\Reply\Exception + * @throws \XF\PrintableException + */ + public function actionSave() + { + $this->assertPostOnly(); + + $entityId = $this->filter('entity_id', 'uint'); + if (!empty($entityId)) { + $entity = $this->assertEntityExists($entityId); + } else { + $entity = $this->createEntity(); + } + + $columns = $this->filter('values', 'array'); + $entity->bulkSet($columns); + + $entity->preSave(); + if ($entity->hasErrors()) { + return $this->error($entity->getErrors()); + } + + $entity->save(); + + return $this->redirect($this->buildLink($this->getRoutePrefix())); + } + + /** + * @param int $entityId + * @return \XF\Mvc\Entity\Entity + * @throws \XF\Mvc\Reply\Exception + */ + protected function assertEntityExists($entityId) + { + return $this->assertRecordExists($this->getShortName(), $entityId); + } + + /** + * @return \XF\Mvc\Entity\Entity + */ + protected function createEntity() + { + return $this->em()->create($this->getShortName()); + } + + /** + * @param \XF\Mvc\Entity\Entity $entity + * @return \XF\Mvc\Reply\View + */ + protected function entityAddEdit($entity) + { + $viewParams = [ + 'entity' => $entity, + 'columns' => [] + ]; + + $structure = $entity->structure(); + + foreach ($structure->columns as $columnName => $column) { + if (empty($column['required']) || + empty($column['type'])) { + continue; + } + + /** @noinspection PhpUndefinedMethodInspection */ + $columnLabel = $entity->getColumnLabel($columnName); + $columnTag = null; + $columnTagOptions = []; + switch ($column['type']) { + case \XF\Mvc\Entity\Entity::STR: + if (!empty($column['maxLength']) && $column['maxLength'] <= 255) { + $columnTag = 'text-box'; + } else { + $columnTag = 'text-area'; + } + break; + } + + $viewParams['columns'][$columnName] = [ + 'label' => $columnLabel, + 'name' => sprintf('values[%s]', $columnName), + 'value' => $entity->get($columnName), + 'tag' => $columnTag, + 'tagOptions' => $columnTagOptions + ]; + } + + foreach ($structure->relations as $relationKey => $relation) { + if (empty($relation['entity']) || + empty($relation['type']) || + $relation['type'] !== \XF\Mvc\Entity\Entity::TO_ONE || + empty($relation['primary']) || + empty($relation['conditions']) || + !is_string($relation['conditions'])) { + continue; + } + + $columnName = $relation['conditions']; + $relationChoices = $this->getRelationChoices($relation['entity']); + + if (count($relationChoices) > 0) { + $viewParams['columns'][$columnName]['tag'] = 'select'; + $viewParams['columns'][$columnName]['tagOptions'] = [ + 'choices' => $relationChoices + ]; + } + } + + return $this->getViewReply('edit', $viewParams); + } + + /** + * @param ParameterBag $params + * @return int + */ + protected function getEntityIdFromParams(ParameterBag $params) + { + $structure = $this->em()->getEntityStructure($this->getShortName()); + if (is_string($structure->primaryKey)) { + return $params->get($structure->primaryKey); + } + + return 0; + } + + /** + * @return int + */ + protected function getPerPage() + { + return 20; + } + + /** + * @return array + */ + protected function getRelationForums() + { + /** @var \XF\Repository\Node $nodeRepo */ + $nodeRepo = \XF::repository('XF:Node'); + $nodeTree = $nodeRepo->createNodeTree($nodeRepo->getFullNodeList()); + + // only list nodes that are forums or contain forums + $nodeTree = $nodeTree->filter(null, function ($id, $node, $depth, $children, $tree) { + return ($children || $node->node_type_id == 'Forum'); + }); + + $choices = []; + + foreach ($nodeTree->getFlattened(0) as $leaf) { + /** @var \XF\Entity\Node $node */ + $node = $leaf['record']; + $choices[] = [ + 'value' => $node->node_id, + 'disabled' => $node->node_type_id !== 'Forum', + 'label' => str_repeat(html_entity_decode('  '), $node->depth) . $node->title + ]; + } + + return $choices; + } + + /** + * @param string $shortName + * @return array + */ + protected function getRelationChoices($shortName) + { + switch ($shortName) { + case 'XF:Forum': + return $this->getRelationForums(); + default: + if (strpos($shortName, $this->getPrefixForClasses()) !== 0) { + return []; + } + } + + $choices = []; + + /** @var \XF\Mvc\Entity\Entity $entity */ + foreach ($this->em()->getFinder($shortName)->fetch() as $entity) { + /** @noinspection PhpUndefinedMethodInspection */ + $entityLabel = $entity->getLabel(); + + $choices[] = [ + 'value' => $entity->getEntityId(), + 'label' => $entityLabel + ]; + } + + return $choices; + } + + /** + * @return array + */ + protected function getViewLinks() + { + $routePrefix = $this->getRoutePrefix(); + $links = [ + 'index' => $routePrefix, + 'save' => sprintf('%s/save', $routePrefix) + ]; + + if ($this->supportsAdding()) { + $links['add'] = sprintf('%s/add', $routePrefix); + } + + if ($this->supportsDeleting()) { + $links['delete'] = sprintf('%s/delete', $routePrefix); + } + + if ($this->supportsEditing()) { + $links['edit'] = sprintf('%s/edit', $routePrefix); + } + + if ($this->supportsViewing()) { + $links['view'] = sprintf('%s/view', $routePrefix); + } + + return $links; + } + + /** + * @return array + */ + protected function getViewPhrases() + { + $prefix = $this->getPrefixForPhrases(); + + $phrases = []; + foreach ([ + 'add', + 'edit', + 'entities', + 'entity', + ] as $partial) { + $phrases[$partial] = \XF::phrase(sprintf('%s_%s', $prefix, $partial)); + } + + return $phrases; + } + + /** + * @param string $action + * @param array $viewParams + * @return \XF\Mvc\Reply\View + */ + protected function getViewReply($action, array $viewParams) + { + $viewClass = sprintf('%s:Entity\%s', $this->getPrefixForClasses(), ucwords($action)); + $templateTitle = sprintf('%s_entity_%s', $this->getPrefixForTemplates(), strtolower($action)); + + $viewParams['links'] = $this->getViewLinks(); + $viewParams['phrases'] = $this->getViewPhrases(); + + return $this->view($viewClass, $templateTitle, $viewParams); + } + + /** + * @return bool + */ + protected function supportsAdding() + { + return true; + } + + /** + * @return bool + */ + protected function supportsDeleting() + { + return true; + } + + /** + * @return bool + */ + protected function supportsEditing() + { + return true; + } + + /** + * @return bool + */ + protected function supportsViewing() + { + return false; + } + + /** + * @return string + */ + abstract protected function getShortName(); + + /** + * @return string + */ + abstract protected function getPrefixForClasses(); + + /** + * @return string + */ + abstract protected function getPrefixForPhrases(); + + /** + * @return string + */ + abstract protected function getPrefixForTemplates(); + + /** + * @return string + */ + abstract protected function getRoutePrefix(); + + // DevHelper/Autogen begins + + /** + * @param \Symfony\Component\Console\Command\Command $command + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param \XF\AddOn\AddOn $addOn + * @throws \XF\PrintableException + */ + public function devHelperAutogen($command, $input, $output, $addOn) + { + /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */ + $helper = $command->getHelper('question'); + + foreach ([ + '_add', + '_edit', + '_entities', + '_entity', + ] as $phraseTitlePartial) { + $phraseTitle = $this->getPrefixForPhrases() . $phraseTitlePartial; + + /** @var \XF\Entity\Phrase $phrase */ + $phrase = $this->finder('XF:Phrase') + ->where('language_id', 0) + ->where('addon_id', $addOn->getAddOnId()) + ->where('title', $phraseTitle) + ->fetchOne(); + if ($phrase) { + $output->writeln( + "Phrase #{$phrase->phrase_id} {$phrase->title} = {$phrase->phrase_text} OK", + \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_VERY_VERBOSE + ); + continue; + } + + $questionText = sprintf('Enter phrase text for %s: ', $phraseTitle); + $question = new \Symfony\Component\Console\Question\Question($questionText); + $question->setValidator(function ($answer) { + $answer = utf8_trim($answer); + if (empty($answer)) { + throw new \InvalidArgumentException('Phrase text cannot be empty'); + } + return $answer; + }); + $phraseText = $helper->ask($input, $output, $question); + + /** @var \XF\Entity\Phrase $newPhrase */ + $newPhrase = $this->em()->create('XF:Phrase'); + $newPhrase->addon_id = $addOn->getAddOnId(); + $newPhrase->language_id = 0; + $newPhrase->title = $phraseTitle; + $newPhrase->phrase_text = $phraseText; + $newPhrase->save(); + + $output->writeln("Phrase #{$newPhrase->phrase_id} {$newPhrase->title} = {$newPhrase->phrase_text} NEW"); + } + + $prefixForTemplates = $this->getPrefixForTemplates(); + foreach ([ + 'delete', + 'edit', + 'list', + ] as $action) { + $templateTitleSource = "devhelper_autogen_ace_{$action}"; + $templateTitleTarget = "{$prefixForTemplates}_entity_{$action}"; + + /** @var \XF\Entity\Template $templateSource */ + $templateSource = $this->finder('XF:Template') + ->where('type', 'admin') + ->where('style_id', 0) + ->where('addon_id', 'DevHelper') + ->where('title', $templateTitleSource) + ->fetchOne(); + if (!$templateSource) { + throw new \LogicException("Source template {$templateTitleSource} not found"); + } + + /** @var \XF\Entity\Template $templateTarget */ + $templateTarget = $this->finder('XF:Template') + ->where('type', 'admin') + ->where('style_id', 0) + ->where('addon_id', $addOn->getAddOnId()) + ->where('title', $templateTitleTarget) + ->fetchOne(); + + if ($templateTarget) { + if ($templateTarget->template === $templateSource->template) { + $output->writeln( + "Template #{$templateTarget->template_id} {$templateTarget->title} OK", + \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_VERY_VERBOSE + ); + } else { + $templateTarget->template = $templateSource->template; + $templateTarget->save(); + + $output->writeln("Template #{$templateTarget->template_id} {$templateTarget->title} UPDATED"); + } + } else { + /** @var \XF\Entity\Template $newTemplate */ + $newTemplate = $this->em()->create('XF:Template'); + $newTemplate->type = 'admin'; + $newTemplate->title = $templateTitleTarget; + $newTemplate->style_id = 0; + $newTemplate->template = $templateSource->template; + $newTemplate->addon_id = $addOn->getAddOnId(); + $newTemplate->save(); + + $output->writeln("Template #{$newTemplate->template_id} {$newTemplate->title} NEW"); + } + } + + $output->writeln(__CLASS__); + } + + // DevHelper/Autogen ends +} diff --git a/Cli/Command/AutoGen.php b/Cli/Command/AutoGen.php new file mode 100644 index 0000000..c8ec786 --- /dev/null +++ b/Cli/Command/AutoGen.php @@ -0,0 +1,129 @@ +devHelperDirPath = dirname(dirname(__DIR__)); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @param AddOn $addOn + * @throws \ReflectionException + * @throws \XF\PrintableException + */ + public function doAdminControllerEntity($input, $output, $addOn) + { + $app = \XF::app(); + $addOnId = $addOn->getAddOnId(); + $addOnDir = $addOn->getAddOnDirectory(); + $classNamePrefix = str_replace('/', '\\', $addOnId); + $baseNamespace = "{$classNamePrefix}\\DevHelper\\Admin\\Controller"; + $baseClass = "{$baseNamespace}\\Entity"; + $basePathPartial = 'Admin/Controller/Entity.php'; + $basePathSource = "{$this->devHelperDirPath}/Autogen/{$basePathPartial}"; + $basePathTarget = "{$addOnDir}/DevHelper/{$basePathPartial}"; + $controllerDirPath = "{$addOnDir}/Admin/Controller"; + $controllerNamespace = "{$classNamePrefix}\\Admin\\Controller"; + + $baseClassRefFound = false; + $controllerClasses = []; + foreach (new \DirectoryIterator($controllerDirPath) as $entry) { + // TODO: process sub-directories + + $entryExtension = $entry->getExtension(); + if ($entryExtension !== 'php') { + continue; + } + + $entryFileName = $entry->getFilename(); + $entryClassName = substr($entryFileName, 0, -strlen($entryExtension) - 1); + $controllerClasses[] = "{$controllerNamespace}\\{$entryClassName}"; + + $entryContents = file_get_contents($entry->getPath()); + if (strpos($entryContents, $baseClass) !== false) { + $baseClassRefFound = true; + } + } + + if ($baseClassRefFound) { + return; + } + + $baseContents = file_get_contents($basePathSource); + $baseContents = preg_replace('/namespace .+;/', "namespace {$baseNamespace};", $baseContents); + if (!File::createDirectory(dirname($basePathTarget), false) || + file_put_contents($basePathTarget, $baseContents) === false) { + throw new \LogicException("Cannot copy {$basePathSource} -> {$basePathTarget}"); + } + + foreach ($controllerClasses as $controllerClass) { + $reflectionClass = new \ReflectionClass($controllerClass); + if ($reflectionClass->isAbstract()) { + continue; + } + + /** @var Entity $controller */ + $controller = new $controllerClass($app, $app->request()); + if (!is_callable([$controller, 'devHelperAutogen'])) { + continue; + } + + $controller->devHelperAutogen($this, $input, $output, $addOn); + } + + $pattern = '#\s+' . preg_quote(self::MARKER_BEGINS, '#') . '.+' . + preg_quote(self::MARKER_ENDS, '#') . '#s'; + $baseContents = preg_replace($pattern, '', $baseContents); + if (file_put_contents($basePathTarget, $baseContents) === false) { + throw new \LogicException("Cannot update {$basePathTarget}"); + } + } + + protected function configure() + { + $this + ->setName('devhelper:autogen') + ->setDescription('Generate code/template/phrase/etc. automatically for the specified add-on') + ->addArgument( + 'id', + InputArgument::REQUIRED, + 'Add-On ID' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $id = $input->getArgument('id'); + $addOn = $this->checkEditableAddOn($id, $error); + if (!$addOn) { + $output->writeln('' . $error . ''); + return 1; + } + + $this->doAdminControllerEntity($input, $output, $addOn); + return 0; + } +} diff --git a/_data/templates.xml b/_data/templates.xml new file mode 100644 index 0000000..19cdbb6 --- /dev/null +++ b/_data/templates.xml @@ -0,0 +1,108 @@ + + + + + + diff --git a/addon.json b/addon.json new file mode 100644 index 0000000..6e34ad8 --- /dev/null +++ b/addon.json @@ -0,0 +1,14 @@ +{ + "legacy_addon_id": "", + "title": "DevHelper", + "description": "", + "version_id": 2000000, + "version_string": "2.0.0", + "dev": "", + "dev_url": "", + "faq_url": "", + "support_url": "", + "extra_urls": [], + "require": [], + "icon": "" +} \ No newline at end of file diff --git a/docker/devhelper-autogen.sh b/docker/devhelper-autogen.sh new file mode 100644 index 0000000..046daaa --- /dev/null +++ b/docker/devhelper-autogen.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +exec cmd-php.sh devhelper:autogen "$@" From 6c60b3a864f8c8246e26001a01f78446508b3caf Mon Sep 17 00:00:00 2001 From: Dao Hoang Son Date: Tue, 17 Apr 2018 11:52:40 +0700 Subject: [PATCH 032/118] Make use of auto_prepend_file --- Dockerfile | 4 ++-- docker/build.sh | 3 +++ docker/cmd-php--xf-addon.sh | 0 docker/cmd-php.sh | 0 docker/devhelper-autogen.sh | 0 docker/xf-addon--create.sh | 0 docker/xf-addon--export.sh | 0 docker/xf-addon--phpcbf.sh | 0 docker/xf-addon--phpcs.sh | 2 +- docker/xf-dev--export--addon.sh | 0 docker/phpcs.xml => phpcs.xml | 1 + prepend.php | 14 ++++++++++++++ 12 files changed, 21 insertions(+), 3 deletions(-) mode change 100644 => 100755 docker/build.sh mode change 100644 => 100755 docker/cmd-php--xf-addon.sh mode change 100644 => 100755 docker/cmd-php.sh mode change 100644 => 100755 docker/devhelper-autogen.sh mode change 100644 => 100755 docker/xf-addon--create.sh mode change 100644 => 100755 docker/xf-addon--export.sh mode change 100644 => 100755 docker/xf-addon--phpcbf.sh mode change 100644 => 100755 docker/xf-addon--phpcs.sh mode change 100644 => 100755 docker/xf-dev--export--addon.sh rename docker/phpcs.xml => phpcs.xml (94%) create mode 100644 prepend.php diff --git a/Dockerfile b/Dockerfile index 9cc7abe..10cfd08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ FROM xfrocks/xenforo:php-apache-7.2.4 -COPY docker/* /usr/local/bin/ -RUN chmod +x /usr/local/bin/*.sh +ENV DEVHELPER_PHP_APACHE_VERSION_ID 2018041701 +COPY docker/* /usr/local/bin/ RUN /usr/local/bin/build.sh WORKDIR "/var/www/html/src/addons" diff --git a/docker/build.sh b/docker/build.sh old mode 100644 new mode 100755 index 74c860e..88e72ea --- a/docker/build.sh +++ b/docker/build.sh @@ -2,8 +2,11 @@ set -e +echo 'PassEnv DEVHELPER_PHP_APACHE_VERSION_ID' >> /etc/apache2/mods-available/env.conf a2enmod env rewrite +echo 'auto_prepend_file=/var/www/html/src/addons/DevHelper/prepend.php' > /usr/local/etc/php/conf.d/DevHelper.ini + for _verb in build-release \ bump-version \ disable \ diff --git a/docker/cmd-php--xf-addon.sh b/docker/cmd-php--xf-addon.sh old mode 100644 new mode 100755 diff --git a/docker/cmd-php.sh b/docker/cmd-php.sh old mode 100644 new mode 100755 diff --git a/docker/devhelper-autogen.sh b/docker/devhelper-autogen.sh old mode 100644 new mode 100755 diff --git a/docker/xf-addon--create.sh b/docker/xf-addon--create.sh old mode 100644 new mode 100755 diff --git a/docker/xf-addon--export.sh b/docker/xf-addon--export.sh old mode 100644 new mode 100755 diff --git a/docker/xf-addon--phpcbf.sh b/docker/xf-addon--phpcbf.sh old mode 100644 new mode 100755 diff --git a/docker/xf-addon--phpcs.sh b/docker/xf-addon--phpcs.sh old mode 100644 new mode 100755 index c147958..056c068 --- a/docker/xf-addon--phpcs.sh +++ b/docker/xf-addon--phpcs.sh @@ -2,7 +2,7 @@ set -e -_phpcsXmlPath='/usr/local/bin/phpcs.xml' +_phpcsXmlPath='/var/www/html/src/addons/DevHelper/phpcs.xml' set -- "--standard=${_phpcsXmlPath}" "$@" if [ -z "$PHPCBF" ]; then diff --git a/docker/xf-dev--export--addon.sh b/docker/xf-dev--export--addon.sh old mode 100644 new mode 100755 diff --git a/docker/phpcs.xml b/phpcs.xml similarity index 94% rename from docker/phpcs.xml rename to phpcs.xml index a507983..3ae9a1f 100644 --- a/docker/phpcs.xml +++ b/phpcs.xml @@ -1,5 +1,6 @@ + */.data/ */_data/ */_no_upload/ */_output/ diff --git a/prepend.php b/prepend.php new file mode 100644 index 0000000..80ea51b --- /dev/null +++ b/prepend.php @@ -0,0 +1,14 @@ + Date: Tue, 17 Apr 2018 13:13:09 +0700 Subject: [PATCH 033/118] Autogen\Admin\Controller\Entity v3 --- Autogen/Admin/Controller/Entity.php | 135 ++++++++++++++++++++-------- _data/templates.xml | 12 ++- 2 files changed, 107 insertions(+), 40 deletions(-) diff --git a/Autogen/Admin/Controller/Entity.php b/Autogen/Admin/Controller/Entity.php index e77cb98..f149264 100644 --- a/Autogen/Admin/Controller/Entity.php +++ b/Autogen/Admin/Controller/Entity.php @@ -3,12 +3,17 @@ namespace DevHelper\Autogen\Admin\Controller; use XF\Admin\Controller\AbstractController; +use XF\Mvc\Entity\Entity as MvcEntity; use XF\Mvc\ParameterBag; +use XF\Mvc\Reply\Error; +use XF\Mvc\Reply\Exception; use XF\Mvc\Reply\Redirect; use XF\Mvc\Reply\View; +use XF\PrintableException; /** - * @version 2 + * @version 3 + * @see \DevHelper\Autogen\Admin\Controller\Entity */ abstract class Entity extends AbstractController { @@ -49,8 +54,8 @@ public function actionAdd() /** * @param ParameterBag $params * @return View|Redirect - * @throws \XF\Mvc\Reply\Exception - * @throws \XF\PrintableException + * @throws Exception + * @throws PrintableException */ public function actionDelete(ParameterBag $params) { @@ -67,12 +72,9 @@ public function actionDelete(ParameterBag $params) return $this->redirect($this->buildLink($this->getRoutePrefix())); } - /** @noinspection PhpUndefinedMethodInspection */ - $entityLabel = $entity->getLabel(); - $viewParams = [ 'entity' => $entity, - 'entityLabel' => $entityLabel + 'entityLabel' => $this->callGetEntityLabel($entity) ]; return $this->getViewReply('delete', $viewParams); @@ -80,8 +82,8 @@ public function actionDelete(ParameterBag $params) /** * @param ParameterBag $params - * @return \XF\Mvc\Reply\View - * @throws \XF\Mvc\Reply\Exception + * @return View + * @throws Exception */ public function actionEdit(ParameterBag $params) { @@ -95,10 +97,10 @@ public function actionEdit(ParameterBag $params) } /** - * @return \XF\Mvc\Reply\Error|\XF\Mvc\Reply\Redirect + * @return Error|Redirect * @throws \Exception - * @throws \XF\Mvc\Reply\Exception - * @throws \XF\PrintableException + * @throws Exception + * @throws PrintableException */ public function actionSave() { @@ -126,8 +128,8 @@ public function actionSave() /** * @param int $entityId - * @return \XF\Mvc\Entity\Entity - * @throws \XF\Mvc\Reply\Exception + * @return MvcEntity + * @throws Exception */ protected function assertEntityExists($entityId) { @@ -135,7 +137,38 @@ protected function assertEntityExists($entityId) } /** - * @return \XF\Mvc\Entity\Entity + * @param MvcEntity $entity + * @param string $columnName + * @return string|null + */ + protected function callGetEntityColumnLabel($entity, $columnName) + { + $callback = [$entity, 'getEntityColumnLabel']; + if (!is_callable($callback)) { + $shortName = $entity->structure()->shortName; + throw new \InvalidArgumentException("{$shortName} does not implement {$callback[1]}"); + } + + return call_user_func($callback, $columnName); + } + + /** + * @param MvcEntity $entity + * @return string|null + */ + protected function callGetEntityLabel($entity) + { + $callback = [$entity, 'getEntityLabel']; + if (!is_callable($callback)) { + $shortName = $entity->structure()->shortName; + throw new \InvalidArgumentException("{$shortName} does not implement {$callback[1]}"); + } + + return call_user_func($callback); + } + + /** + * @return MvcEntity */ protected function createEntity() { @@ -143,8 +176,8 @@ protected function createEntity() } /** - * @param \XF\Mvc\Entity\Entity $entity - * @return \XF\Mvc\Reply\View + * @param MvcEntity $entity + * @return View */ protected function entityAddEdit($entity) { @@ -156,17 +189,31 @@ protected function entityAddEdit($entity) $structure = $entity->structure(); foreach ($structure->columns as $columnName => $column) { - if (empty($column['required']) || - empty($column['type'])) { + if (empty($column['type']) || + $columnName === $structure->primaryKey) { continue; } - /** @noinspection PhpUndefinedMethodInspection */ - $columnLabel = $entity->getColumnLabel($columnName); + $columnLabel = $this->callGetEntityColumnLabel($entity, $columnName); + if (empty($columnLabel)) { + continue; + } + + if (!$entity->exists() && !empty($column['default'])) { + $entity->set($columnName, $column['default']); + } + $columnTag = null; $columnTagOptions = []; switch ($column['type']) { - case \XF\Mvc\Entity\Entity::STR: + case MvcEntity::INT: + $columnTag = 'number-box'; + break; + case MvcEntity::UINT: + $columnTag = 'number-box'; + $columnTagOptions['min'] = 0; + break; + case MvcEntity::STR: if (!empty($column['maxLength']) && $column['maxLength'] <= 255) { $columnTag = 'text-box'; } else { @@ -187,22 +234,27 @@ protected function entityAddEdit($entity) foreach ($structure->relations as $relationKey => $relation) { if (empty($relation['entity']) || empty($relation['type']) || - $relation['type'] !== \XF\Mvc\Entity\Entity::TO_ONE || + $relation['type'] !== MvcEntity::TO_ONE || empty($relation['primary']) || - empty($relation['conditions']) || - !is_string($relation['conditions'])) { + empty($relation['conditions'])) { continue; } $columnName = $relation['conditions']; - $relationChoices = $this->getRelationChoices($relation['entity']); + if (!is_string($columnName) || + !isset($viewParams['columns'][$columnName])) { + continue; + } + $columnViewParamRef = &$viewParams['columns'][$columnName]; - if (count($relationChoices) > 0) { - $viewParams['columns'][$columnName]['tag'] = 'select'; - $viewParams['columns'][$columnName]['tagOptions'] = [ - 'choices' => $relationChoices - ]; + $relationChoices = $this->getRelationChoices($relation['entity']); + if (count($relationChoices) === 0) { + $columnViewParamRef['tag'] = 'text-box'; + continue; } + + $columnViewParamRef['tag'] = 'select'; + $columnViewParamRef['tagOptions'] = ['choices' => $relationChoices]; } return $this->getViewReply('edit', $viewParams); @@ -276,14 +328,11 @@ protected function getRelationChoices($shortName) $choices = []; - /** @var \XF\Mvc\Entity\Entity $entity */ + /** @var MvcEntity $entity */ foreach ($this->em()->getFinder($shortName)->fetch() as $entity) { - /** @noinspection PhpUndefinedMethodInspection */ - $entityLabel = $entity->getLabel(); - $choices[] = [ 'value' => $entity->getEntityId(), - 'label' => $entityLabel + 'label' => $this->callGetEntityLabel($entity) ]; } @@ -343,7 +392,7 @@ protected function getViewPhrases() /** * @param string $action * @param array $viewParams - * @return \XF\Mvc\Reply\View + * @return View */ protected function getViewReply($action, array $viewParams) { @@ -427,6 +476,18 @@ public function devHelperAutogen($command, $input, $output, $addOn) /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */ $helper = $command->getHelper('question'); + $entity = $this->createEntity(); + try { + $this->callGetEntityLabel($entity); + } catch (\InvalidArgumentException $e) { + $output->writeln("{$e->getMessage()}"); + } + try { + $this->callGetEntityColumnLabel($entity, __METHOD__); + } catch (\InvalidArgumentException $e) { + $output->writeln("{$e->getMessage()}"); + } + foreach ([ '_add', '_edit', diff --git a/_data/templates.xml b/_data/templates.xml index 19cdbb6..5bef90b 100644 --- a/_data/templates.xml +++ b/_data/templates.xml @@ -22,7 +22,7 @@