Просмотр исходного кода

Version 1.2.14 Magic Table of Contents

Trendschau 6 лет назад
Родитель
Сommit
8c6d4db4dc
37 измененных файлов с 576 добавлено и 313 удалено
  1. 2 1
      .gitignore
  2. 1 1
      cache/lastCache.txt
  3. 0 0
      content/00-Welcome/01-Write-Content.md
  4. 0 0
      content/00-Welcome/02-Markdown-Test.md
  5. 0 2
      content/00-Welcome/index.md
  6. 2 2
      system/Controllers/AuthController.php
  7. 159 28
      system/Controllers/ContentApiController.php
  8. 1 1
      system/Controllers/ContentBackendController.php
  9. 1 0
      system/Controllers/SetupController.php
  10. 29 14
      system/Extensions/ParsedownExtension.php
  11. 3 3
      system/Middleware/RedirectIfUnauthenticated.php
  12. 24 2
      system/Models/Folder.php
  13. 6 1
      system/Models/User.php
  14. 37 32
      system/author/auth/login.twig
  15. 31 31
      system/author/auth/setup.twig
  16. 1 1
      system/author/auth/welcome.twig
  17. 6 0
      system/author/css/fontello/config.json
  18. 1 0
      system/author/css/fontello/css/fontello-codes.css
  19. 3 3
      system/author/css/fontello/css/fontello-embedded.css
  20. 1 0
      system/author/css/fontello/css/fontello-ie7-codes.css
  21. 1 0
      system/author/css/fontello/css/fontello-ie7.css
  22. 8 7
      system/author/css/fontello/css/fontello.css
  23. 9 8
      system/author/css/fontello/demo.html
  24. BIN
      system/author/css/fontello/font/fontello.eot
  25. 2 0
      system/author/css/fontello/font/fontello.svg
  26. BIN
      system/author/css/fontello/font/fontello.ttf
  27. BIN
      system/author/css/fontello/font/fontello.woff
  28. BIN
      system/author/css/fontello/font/fontello.woff2
  29. 138 102
      system/author/css/style.css
  30. 25 23
      system/author/editor/editor-blox.twig
  31. 18 24
      system/author/editor/publish-controller.twig
  32. 40 5
      system/author/js/vue-blox.js
  33. 1 1
      system/author/js/vue-navi.js
  34. 3 0
      system/author/js/vue-publishcontroller.js
  35. 3 19
      system/author/partials/editorNavi.twig
  36. 2 2
      system/author/settings/user.twig
  37. 18 0
      system/system.php

+ 2 - 1
.gitignore

@@ -8,6 +8,7 @@ plugins/finalwords
 plugins/joblistings
 plugins/landingpage
 plugins/mail
+plugins/newsletter
 plugins/textadds
 plugins/version
 settings/settings.yaml
@@ -17,4 +18,4 @@ system/vendor
 tests
 themes/monograf
 zips
-zip.php
+build.php

+ 1 - 1
cache/lastCache.txt

@@ -1 +1 @@
-1556962245
+1558123679

+ 0 - 0
content/00-Welcome/02-Write-Content.md → content/00-Welcome/01-Write-Content.md


+ 0 - 0
content/00-Welcome/04-Markdown-Test.md → content/00-Welcome/02-Markdown-Test.md


+ 0 - 2
content/00-Welcome/index.md

@@ -2,5 +2,3 @@
 
 Great that you give Typemill a try!! Typemill is a small open source cms and a project in work. You will probably miss some important features, but I am working hard to add everything that is needed for a handy and productive writing-system.
 
-Read the short introduction about "writing content" before you start or simply play around and try it out.
-

+ 2 - 2
system/Controllers/AuthController.php

@@ -113,11 +113,11 @@ class AuthController extends Controller
 		{
 			$user = new User();
 			$userdata = $user->getUser($params['username']);
-			
+
 			if($userdata && password_verify($params['password'], $userdata['password']))
 			{
 				$user->login($userdata['username']);
-				
+
 				/* clear the user login attemps */
 				if($userLogins)
 				{

+ 159 - 28
system/Controllers/ContentApiController.php

@@ -244,7 +244,7 @@ class ContentApiController extends ContentController
 		$this->params 	= $request->getParams();
 		$this->uri 		= $request->getUri();
 		
-		# url is only needed, if an active page is moved
+		# url is only needed, if an active page is moved to another folder, so user has to be redirected to the new url
 		$url 			= false;
 		
 		# set structure
@@ -292,8 +292,8 @@ class ContentApiController extends ContentController
 		}
 		elseif($this->params['active'] == 'active')
 		{
-			# an active file has been moved to another folder
-			$url = $this->uri->getBaseUrl() . '/tm/content' . $newFolder->urlRelWoF . '/' . $item->slug;
+			# an active file has been moved to another folder, so send new url with response
+			$url = $this->uri->getBaseUrl() . '/tm/content/' . $this->settings['editor'] . $newFolder->urlRelWoF . '/' . $item->slug;
 		}
 		
 		# add item to newFolder
@@ -305,7 +305,7 @@ class ContentApiController extends ContentController
 		# initialise write object
 		$write = new Write();
 
-		# iterate through the whole content of the new folder
+		# iterate through the whole content of the new folder to rename the files
 		$writeError = false;
 		foreach($folderContent as $folderItem)
 		{
@@ -591,15 +591,37 @@ class ContentApiController extends ContentController
 		# needed for ToC links
 		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
 		
+		# flag for TOC
+		$toc = false;
+
+		# loop through mardkown-array and create html-blocks
 		foreach($content as $key => $block)
 		{
-			/* parse markdown-file to content-array */
+			# parse markdown-file to content-array
 			$contentArray 	= $parsedown->text($block);
 
-			/* parse markdown-content-array to content-string */
+			if($block == '[TOC]')
+			{
+				$toc = $key;
+			}
+
+			# parse markdown-content-array to content-string
 			$content[$key]	= ['id' => $key, 'html' => $parsedown->markup($contentArray, $relurl)];
 		}
 
+		if($toc)
+		{
+			$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
+			$content[$toc] = ['id' => $toc, 'html' => $tocMarkup];
+		}
+
+		/*
+		$footnotes = $parsedown->getFootnotes();
+
+		print_r($footnotes);
+		die();
+		*/
+		
 		return $response->withJson(array('data' => $content, 'errors' => false));
 	}
 
@@ -685,6 +707,7 @@ class ContentApiController extends ContentController
 		{
 			# update the internal structure
 			$this->setStructure($draft = true, $cache = false);
+			$this->content = $pageMarkdown;
 		}
 		else
 		{
@@ -695,17 +718,93 @@ class ContentApiController extends ContentController
 		$parsedown->setSafeMode(true);
 
 		/* parse markdown-file to content-array */
-		$blockArray 	= $parsedown->text($blockMarkdown);
+		$blockArray = $parsedown->text($blockMarkdown);
 		
+		# we assume that toc is not relevant
+		$toc = false;
+
 		# needed for ToC links
-		$relurl 		= '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
+		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
 		
-		/* parse markdown-content-array to content-string */
-		$blockHTML		= $parsedown->markup($blockArray, $relurl);
+		if($blockMarkdown == '[TOC]')
+		{
+			# if block is table of content itself, then generate the table of content
+			$tableofcontent = $this->generateToc();
+
+			# and only use the html-markup
+			$blockHTML = $tableofcontent['html'];
+		}
+		else
+		{
+			# parse markdown-content-array to content-string
+			$blockHTML = $parsedown->markup($blockArray, $relurl);
+			
+			# if it is a headline
+			if($blockMarkdown[0] == '#')
+			{
+				# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
+				$toc = $this->generateToc();
+			}
+		}
 
-		return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'errors' => false));
+		return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
 	}
-	
+
+	protected function generateToc()
+	{
+		# we assume that page has no table of content
+		$toc = false;
+
+		# make sure $this->content is updated
+		$content = $this->content;
+
+		if($content == '')
+		{
+			$content = [];
+		}
+		
+		# initialize parsedown extension
+		$parsedown = new ParsedownExtension();
+		
+		# if content is not an array, then transform it
+		if(!is_array($content))
+		{
+			# turn markdown into an array of markdown-blocks
+			$content = $parsedown->markdownToArrayBlocks($content);
+		}
+		
+		# needed for ToC links
+		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
+		
+		# loop through mardkown-array and create html-blocks
+		foreach($content as $key => $block)
+		{
+			# parse markdown-file to content-array
+			$contentArray 	= $parsedown->text($block);
+			
+			if($block == '[TOC]')
+			{
+				# toc is true and holds the key of the table of content now
+				$toc = $key;
+			}
+
+			# parse markdown-content-array to content-string
+			$content[$key]	= ['id' => $key, 'html' => $parsedown->markup($contentArray, $relurl)];
+		}
+
+		# if page has a table of content
+		if($toc)
+		{
+			# generate the toc markup
+			$tocMarkup = $parsedown->buildTOC($parsedown->headlines);
+
+			# toc holds the id of the table of content and the html-markup now
+			$toc = ['id' => $toc, 'html' => $tocMarkup];
+		}
+
+		return $toc;
+	}
+
 	public function updateBlock(Request $request, Response $response, $args)
 	{
 		/* get params from call */
@@ -791,6 +890,9 @@ class ContentApiController extends ContentController
 		{
 			# update the internal structure
 			$this->setStructure($draft = true, $cache = false);
+
+			# updated the content variable
+			$this->content = $pageMarkdown;
 		}
 		else
 		{
@@ -810,13 +912,34 @@ class ContentApiController extends ContentController
 			$blockArray 	= $parsedown->text($blockMarkdown);
 		}
 		
+		# we assume that toc is not relevant
+		$toc = false;
+
 		# needed for ToC links
 		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
 		
-		/* parse markdown-content-array to content-string */
-		$blockHTML		= $parsedown->markup($blockArray, $relurl);
+		if($blockMarkdown == '[TOC]')
+		{
+			# if block is table of content itself, then generate the table of content
+			$tableofcontent = $this->generateToc();
 
-		return $response->withJson(array('content' => ['id' => $id, 'html' => $blockHTML], 'markdown' => $blockMarkdown, 'id' => $id, 'errors' => false));
+			# and only use the html-markup
+			$blockHTML = $tableofcontent['html'];
+		}
+		else
+		{
+			# parse markdown-content-array to content-string
+			$blockHTML = $parsedown->markup($blockArray, $relurl);
+			
+			# if it is a headline
+			if($blockMarkdown[0] == '#')
+			{
+				# then the TOC holds either false (if no toc used in the page) or it holds an object with the id and toc-markup
+				$toc = $this->generateToc();
+			}
+		}
+
+		return $response->withJson(array('content' => [ 'id' => $id, 'html' => $blockHTML ] , 'markdown' => $blockMarkdown, 'id' => $id, 'toc' => $toc, 'errors' => false));
 	}
 	
 	public function moveBlock(Request $request, Response $response, $args)
@@ -869,10 +992,10 @@ class ContentApiController extends ContentController
 			# if the block does not exists, return an error
 			return $response->withJson(array('data' => false, 'errors' => 'The ID of the content-block is wrong.'), 404);
 		}
-				
+
 		$extract = array_splice($pageMarkdown, $oldIndex, 1);
 		array_splice($pageMarkdown, $newIndex, 0, $extract);
-			
+	
 		# encode the content into json
 		$pageJson = json_encode($pageMarkdown);
 
@@ -884,30 +1007,31 @@ class ContentApiController extends ContentController
 		{
 			# update the internal structure
 			$this->setStructure($draft = true, $cache = false);
+
+			# update this content
+			$this->content = $pageMarkdown;
 		}
 		else
 		{
 			return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
 		}
 
+		# we assume that toc is not relevant
+		$toc = false;
+
 		# needed for ToC links
 		$relurl = '/tm/content/' . $this->settings['editor'] . '/' . $this->item->urlRel;
 
-		# generate html array
-		$pageHTML = [];
-		foreach($pageMarkdown as $key => $markdownBlock)
+		# if the moved item is a headline
+		if($extract[0][0] == '#')
 		{
-			/* parse markdown-file to content-array */
-			$contentArray 	= $parsedown->text($markdownBlock);
-
-			/* parse markdown-content-array to content-string */
-			$pageHTML[$key]	= ['id' => $key, 'html' => $parsedown->markup($contentArray, $relurl)];
+			$toc = $this->generateToc();
 		}
 
 		# if it is the title, then delete the "# " if it exists
 		$pageMarkdown[0] = trim($pageMarkdown[0], "# ");
 
-		return $response->withJson(array('markdown' => $pageMarkdown,  'html' => $pageHTML, 'errors' => false));
+		return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => false));
 	}
 
 	public function deleteBlock(Request $request, Response $response, $args)
@@ -1000,8 +1124,15 @@ class ContentApiController extends ContentController
 		{
 			return $response->withJson(['errors' => ['message' => 'Could not write to file. Please check if the file is writable']], 404);
 		}
-				
-		return $response->withJson(array('markdown' => $pageMarkdown, 'errors' => $errors));
+		
+		$toc = false;
+
+		if($contentBlock[0] == '#')
+		{
+			$toc = $this->generateToc();
+		}
+
+		return $response->withJson(array('markdown' => $pageMarkdown, 'toc' => $toc, 'errors' => $errors));
 	}
 
 	public function createImage(Request $request, Response $response, $args)

+ 1 - 1
system/Controllers/ContentBackendController.php

@@ -71,7 +71,7 @@ class ContentBackendController extends ContentController
 				$content = trim($contentParts[1]);
 			}
 		}
-		
+
 		return $this->render($response, 'editor/editor-raw.twig', array('navigation' => $this->structure, 'title' => $title, 'content' => $content, 'item' => $this->item, 'settings' => $this->settings ));
 	}
 	

+ 1 - 0
system/Controllers/SetupController.php

@@ -20,6 +20,7 @@ class SetupController extends Controller
 		try{ $checkFolder->checkPath('settings/users'); }catch(\Exception $e){ $systemcheck['error'][] = $e->getMessage(); }
 		try{ $checkFolder->checkPath('content'); }catch(\Exception $e){ $systemcheck['error'][] = $e->getMessage(); }
 		try{ $checkFolder->checkPath('cache'); }catch(\Exception $e){ $systemcheck['error'][] = $e->getMessage(); }
+		try{ $checkFolder->checkPath('media'); }catch(\Exception $e){ $systemcheck['error'][] = $e->getMessage(); }
 
 		$systemcheck = empty($systemcheck) ? false : $systemcheck;
 

+ 29 - 14
system/Extensions/ParsedownExtension.php

@@ -57,7 +57,21 @@ class ParsedownExtension extends \ParsedownExtra
         }
 		
 		return $markup;
-	}
+    }
+    
+
+    public function getFootnotes()
+    {
+        # add footnotes
+        if (isset($this->DefinitionData['Footnote']))
+        {
+            $Element = $this->buildFootnoteElement();
+
+            $footnotes = "\n" . $this->element($Element);
+        }
+
+        return $footnotes;
+    }
 			
     # TableOfContents
 
@@ -71,28 +85,29 @@ class ParsedownExtension extends \ParsedownExtra
 
     # Header
 	
-	private $headlines = array();
+	public $headlines = array();
 	
     protected function blockHeader($Line)
     {
         if (isset($Line['text'][1]))
         {
-            $level = 1;
-
-            while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
-            {
-                $level ++;
-            }
+            $level = strspn($Line['text'], '#');
 
             if ($level > 6)
             {
                 return;
             }
 
-            $text = trim($Line['text'], '# ');
-
+            $text = trim($Line['text'], '#');
 			$headline = URLify::filter($Line['text']);
-						
+
+            if ($this->strictMode and isset($text[0]) and $text[0] !== ' ')
+            {
+                return;
+            }
+    
+            $text = trim($text, ' ');
+    						
 			$Block = array(
 				'element' => array(
 					'name' => 'h' . min(6, $level),
@@ -112,7 +127,7 @@ class ParsedownExtension extends \ParsedownExtra
 	
 	# build the markup for table of contents 
 	
-	protected function buildTOC($headlines)
+	public function buildTOC($headlines)
 	{
 		$markup = '<ul class="TOC">';
 		
@@ -140,7 +155,7 @@ class ParsedownExtension extends \ParsedownExtra
 					$markup .= '</li></ul>';
 					$thisLevel--;
 				}
-			}			
+			}
 		}
 		
 		$markup .= '</ul>';
@@ -188,7 +203,7 @@ class ParsedownExtension extends \ParsedownExtra
 	
 	public $footnoteCount = 0;
 	
-    protected function buildFootnoteElement()
+    public function buildFootnoteElement()
     {
         $Element = array(
             'name' => 'div',

+ 3 - 3
system/Middleware/RedirectIfUnauthenticated.php

@@ -7,7 +7,7 @@ use Slim\Http\Request;
 use Slim\Http\Response;
 
 class RedirectIfUnauthenticated
-{	
+{
 	protected $router;
 	
 	public function __construct(RouterInterface $router, $flash)
@@ -16,12 +16,12 @@ class RedirectIfUnauthenticated
 	}
 
 	public function __invoke(Request $request, Response $response, $next)
-	{		
+	{
 		if(!isset($_SESSION['login']))
 		{
 			return $response->withRedirect($this->router->pathFor('auth.show'));
 		}
-				
+
 		return $next($request, $response);
 	}
 }

+ 24 - 2
system/Models/Folder.php

@@ -100,9 +100,20 @@ class Folder
 			{
 				$nameParts = self::getStringParts($key);
 				
+				$fileType = false; 
+				if(array_search('index.md', $name))
+				{
+					$fileType = 'md';
+				}
+				elseif(array_search('index.txt', $name))
+				{
+					$fileType = 'txt';
+				}
+
 				$item->originalName 	= $key;
 				$item->elementType		= 'folder';
-				$item->index			= array_search('index.md', $name) === false ? false : true;
+				$item->index			= $fileType;
+				$item->fileType			= $fileType;
 				$item->order 			= count($nameParts) > 1 ? array_shift($nameParts) : NULL;
 				$item->name 			= implode(" ",$nameParts);
 				$item->name				= iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
@@ -161,6 +172,7 @@ class Folder
 		{
 			if($item->urlRel === $url)
 			{
+				# set item active, needed for move item in navigation
 				$item->active = true;
 				$result = $item;
 			}
@@ -314,7 +326,6 @@ class Folder
 		return array('structure' => $structure, 'item' => $item);
 	}
 	
-				
 	/* get breadcrumb as copied array, set elements active in original and mark parent element in original */
 	public static function getBreadcrumb($content, $searchArray, $i = NULL, $breadcrumb = NULL)
 	{
@@ -323,11 +334,22 @@ class Folder
 		while($i < count($searchArray))
 		{
 			$item = $content[$searchArray[$i]];
+
+			if($i == count($searchArray)-1)
+			{
+				$item->active = true;
+			}
+			else
+			{
+				$item->activeParent = true;
+			}
+			/*
 			$item->active = true;
 			if($i == count($searchArray)-2)
 			{
 				$item->activeParent = true; 
 			}
+			*/
 
 			$copy = clone($item);
 			if($copy->elementType == 'folder')

+ 6 - 1
system/Models/User.php

@@ -78,11 +78,16 @@ class User extends WriteYaml
 	public function login($username)
 	{
 		$user = $this->getUser($username);
+
 		if($user)
 		{
+			$user['lastlogin'] = time();
+			unset($user['password']);
+			$this->updateUser($user);
+
 			$_SESSION['user'] 	= $user['username'];
 			$_SESSION['role'] 	= $user['userrole'];
-			$_SESSION['login'] 	= true;
+			$_SESSION['login'] 	= $user['lastlogin'];
 		}
 	}
 	

+ 37 - 32
system/author/auth/login.twig

@@ -4,39 +4,44 @@
 {% block content %}
 
 	<div class="setupWrapper">
-
-		<form method="POST" action="{{ path_for("auth.login") }}" autocomplete="off">
 		
-			<fieldset class="auth">
-				<div class="formElement{{ errors.username ? ' errors' : '' }}">
-					<label for="username">Username <abbr title="required">*</abbr></label>
-					<input type="text" name="username" value="{{ old.username }}" required>
-					{% if errors.signup_username %}
-						<span class="error">{{ errors.username | first }}</span>
-					{% endif %}
-				</div>
-				<div class="formElement{{ errors.password ? ' errors' : '' }}">
-					<label for="password">Password <abbr title="required">*</abbr></label>
-					<input type="password" name="password" required autoomplete="off">
-					{% if errors.password %}
-						<span class="error">{{ errors.password | first }}</span>
-					{% endif %}
-				</div>
-			</fieldset>			
+		<div class="setupContent">
+			<p><i class="icon-bookmark-empty"></i>Remember to bookmark this page</p>
+		</div>
+		<div class="authformWrapper">
+			<form method="POST" action="{{ path_for("auth.login") }}" autocomplete="off">
+			
+				<fieldset class="auth">
+					<div class="formElement{{ errors.username ? ' errors' : '' }}">
+						<label for="username">Username <abbr title="required">*</abbr></label>
+						<input type="text" name="username" value="{{ old.username }}" required>
+						{% if errors.signup_username %}
+							<span class="error">{{ errors.username | first }}</span>
+						{% endif %}
+					</div>
+					<div class="formElement{{ errors.password ? ' errors' : '' }}">
+						<label for="password">Password <abbr title="required">*</abbr></label>
+						<input type="password" name="password" required autoomplete="off">
+						{% if errors.password %}
+							<span class="error">{{ errors.password | first }}</span>
+						{% endif %}
+					</div>
+				</fieldset>
 
-			<div class="loginarea" id="loginarea">			
-				<input type="submit" value="Login" id="loginbutton" class="loginbutton" />
-				{{ csrf_field() | raw }}
-				
-				{% if messages.time %}
-					<div id="counter" class="counter">wait <span id="wait">{{ messages.time }}</span> sec</div>
-					<div class="forgotpw"><a href="https://typemill.net/writers/forgot-password" target="_blank">Forgot password?</a></div>
-				{% endif %}			
-			</div>
-		</form>		
-		
+				<div class="loginarea" id="loginarea">			
+					<input type="submit" value="Login" id="loginbutton" class="loginbutton" />
+					{{ csrf_field() | raw }}
+					
+					{% if messages.time %}
+						<div id="counter" class="counter">wait <span id="wait">{{ messages.time }}</span> sec</div>
+						<div class="forgotpw"><a href="https://typemill.net/writers/forgot-password" target="_blank">Forgot password?</a></div>
+					{% endif %}			
+				</div>
+			</form>		
+		</div>
+		<div class="setupContent">
+			<p><a href="{{ base_url() }}">back to startpage</a></p>
+		</div>
 	</div>
-	<footer>
-		<a href="{{ base_url() }}">back to startpage</a>
-	</footer>
+	<footer></footer>
 {% endblock %}

+ 31 - 31
system/author/auth/setup.twig

@@ -4,38 +4,38 @@
 {% block content %}
 
 	<div class="setupWrapper">
+		<div class="authformWrapper">
+			<form method="POST" action="{{ path_for('setup.create') }}" autocomplete="off">
+			
+				<fieldset class="auth">
+					<div class="formElement{{ errors.username ? ' errors' : '' }}">
+						<label for="username">Username <abbr title="required">*</abbr></label>
+						<input type="text" name="username" value="{{ old.username }}" required>
+						{% if errors.username %}
+							<span class="error">{{ errors.username | first }}</span>
+						{% endif %}
+					</div>
+					<div class="formElement{{ errors.email ? ' errors' : '' }}">
+						<label for="email">E-Mail <abbr title="required">*</abbr></label>
+						<input type="text" name="email" value="{{ old.email }}" required>
+						{% if errors.email %}
+							<span class="error">{{ errors.email | first }}</span>
+						{% endif %}
+					</div>
+					<div class="formElement{{ errors.password ? ' errors' : '' }}">
+						<label for="password">Password <abbr title="required">*</abbr></label>
+						<input type="password" name="password" required autocomplete="off">
+						{% if errors.password %}
+							<span class="error">{{ errors.password | first }}</span>
+						{% endif %}
+					</div>
+				</fieldset>
 
-		<form method="POST" action="{{ path_for('setup.create') }}" autocomplete="off">
-		
-			<fieldset class="auth">
-				<div class="formElement{{ errors.username ? ' errors' : '' }}">
-					<label for="username">Username <abbr title="required">*</abbr></label>
-					<input type="text" name="username" value="{{ old.username }}" required>
-					{% if errors.username %}
-						<span class="error">{{ errors.username | first }}</span>
-					{% endif %}
-				</div>
-				<div class="formElement{{ errors.email ? ' errors' : '' }}">
-					<label for="email">E-Mail <abbr title="required">*</abbr></label>
-					<input type="text" name="email" value="{{ old.email }}" required>
-					{% if errors.email %}
-						<span class="error">{{ errors.email | first }}</span>
-					{% endif %}
-				</div>
-				<div class="formElement{{ errors.password ? ' errors' : '' }}">
-					<label for="password">Password <abbr title="required">*</abbr></label>
-					<input type="password" name="password" required autocomplete="off">
-					{% if errors.password %}
-						<span class="error">{{ errors.password | first }}</span>
-					{% endif %}
-				</div>
-			</fieldset>
-
-			<input type="submit" value="Create User" />
-			{{ csrf_field() | raw }}
-					
-		</form>
-		
+				<input type="submit" value="Create User" />
+				{{ csrf_field() | raw }}
+						
+			</form>
+		</div>		
 	</div>
 	
 {% endblock %}

+ 1 - 1
system/author/auth/welcome.twig

@@ -11,7 +11,7 @@
 				<h1>Hurra!</h1>
 				<p>Your account has been created and you are logged in now.</p>
 				<p><strong>Next step:</strong> Visit the author panel and setup your new website. You can configure the system, choose themes and add plugins.</p>
-				<p><strong>New:</strong> Have you ever heared of definition lists? With this latest version you can add this exotic and very semantic markdown-feature easily with the visual editor. </p>
+				<p><strong>New:</strong> Table of content (TOC) are nice and helpful for long content pages and now the table of content will magically update while you write your page in the visual editor. Fancy stuff!!</p>
 				<p><strong>Get help:</strong> If you have any questions, please consult the <a target="_blank" href="https://typemill.net/typemill"><i class="icon-link-ext"></i> docs</a> or open a new issue on <a target="_blank" href="https://github.com/typemill/typemill"><i class="icon-link-ext"></i> github</a>.</p>
 			</div>
 			<a class="button" href="{{ path_for('settings.show') }}">Configure your website</a>

+ 6 - 0
system/author/css/fontello/config.json

@@ -191,6 +191,12 @@
       "css": "resize-vertical",
       "code": 59407,
       "src": "fontawesome"
+    },
+    {
+      "uid": "2f5ef6f6b7aaebc56458ab4e865beff5",
+      "css": "bookmark-empty",
+      "code": 61591,
+      "src": "fontawesome"
     }
   ]
 }

+ 1 - 0
system/author/css/fontello/css/fontello-codes.css

@@ -18,6 +18,7 @@
 .icon-math:before { content: '\f01a'; } /* '' */
 .icon-move:before { content: '\f047'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
+.icon-bookmark-empty:before { content: '\f097'; } /* '' */
 .icon-list-bullet:before { content: '\f0ca'; } /* '' */
 .icon-list-numbered:before { content: '\f0cb'; } /* '' */
 .icon-underline:before { content: '\f0cd'; } /* '' */

Разница между файлами не показана из-за своего большого размера
+ 3 - 3
system/author/css/fontello/css/fontello-embedded.css


+ 1 - 0
system/author/css/fontello/css/fontello-ie7-codes.css

@@ -18,6 +18,7 @@
 .icon-math { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01a;&nbsp;'); }
 .icon-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf047;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
+.icon-bookmark-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf097;&nbsp;'); }
 .icon-list-bullet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ca;&nbsp;'); }
 .icon-list-numbered { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cb;&nbsp;'); }
 .icon-underline { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cd;&nbsp;'); }

+ 1 - 0
system/author/css/fontello/css/fontello-ie7.css

@@ -29,6 +29,7 @@
 .icon-math { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf01a;&nbsp;'); }
 .icon-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf047;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
+.icon-bookmark-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf097;&nbsp;'); }
 .icon-list-bullet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0ca;&nbsp;'); }
 .icon-list-numbered { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cb;&nbsp;'); }
 .icon-underline { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0cd;&nbsp;'); }

+ 8 - 7
system/author/css/fontello/css/fontello.css

@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?30081562');
-  src: url('../font/fontello.eot?30081562#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?30081562') format('woff2'),
-       url('../font/fontello.woff?30081562') format('woff'),
-       url('../font/fontello.ttf?30081562') format('truetype'),
-       url('../font/fontello.svg?30081562#fontello') format('svg');
+  src: url('../font/fontello.eot?35517051');
+  src: url('../font/fontello.eot?35517051#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?35517051') format('woff2'),
+       url('../font/fontello.woff?35517051') format('woff'),
+       url('../font/fontello.ttf?35517051') format('truetype'),
+       url('../font/fontello.svg?35517051#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?30081562#fontello') format('svg');
+    src: url('../font/fontello.svg?35517051#fontello') format('svg');
   }
 }
 */
@@ -74,6 +74,7 @@
 .icon-math:before { content: '\f01a'; } /* '' */
 .icon-move:before { content: '\f047'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
+.icon-bookmark-empty:before { content: '\f097'; } /* '' */
 .icon-list-bullet:before { content: '\f0ca'; } /* '' */
 .icon-list-numbered:before { content: '\f0cb'; } /* '' */
 .icon-underline:before { content: '\f0cd'; } /* '' */

+ 9 - 8
system/author/css/fontello/demo.html

@@ -229,11 +229,11 @@ body {
 }
 @font-face {
       font-family: 'fontello';
-      src: url('./font/fontello.eot?59871380');
-      src: url('./font/fontello.eot?59871380#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?59871380') format('woff'),
-           url('./font/fontello.ttf?59871380') format('truetype'),
-           url('./font/fontello.svg?59871380#fontello') format('svg');
+      src: url('./font/fontello.eot?82894013');
+      src: url('./font/fontello.eot?82894013#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?82894013') format('woff'),
+           url('./font/fontello.ttf?82894013') format('truetype'),
+           url('./font/fontello.svg?82894013#fontello') format('svg');
       font-weight: normal;
       font-style: normal;
     }
@@ -325,21 +325,22 @@ body {
         <div class="the-icons span3" title="Code: 0xf01a"><i class="demo-icon icon-math">&#xf01a;</i> <span class="i-name">icon-math</span><span class="i-code">0xf01a</span></div>
         <div class="the-icons span3" title="Code: 0xf047"><i class="demo-icon icon-move">&#xf047;</i> <span class="i-name">icon-move</span><span class="i-code">0xf047</span></div>
         <div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext">&#xf08e;</i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
-        <div class="the-icons span3" title="Code: 0xf0ca"><i class="demo-icon icon-list-bullet">&#xf0ca;</i> <span class="i-name">icon-list-bullet</span><span class="i-code">0xf0ca</span></div>
+        <div class="the-icons span3" title="Code: 0xf097"><i class="demo-icon icon-bookmark-empty">&#xf097;</i> <span class="i-name">icon-bookmark-empty</span><span class="i-code">0xf097</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf0ca"><i class="demo-icon icon-list-bullet">&#xf0ca;</i> <span class="i-name">icon-list-bullet</span><span class="i-code">0xf0ca</span></div>
         <div class="the-icons span3" title="Code: 0xf0cb"><i class="demo-icon icon-list-numbered">&#xf0cb;</i> <span class="i-name">icon-list-numbered</span><span class="i-code">0xf0cb</span></div>
         <div class="the-icons span3" title="Code: 0xf0cd"><i class="demo-icon icon-underline">&#xf0cd;</i> <span class="i-name">icon-underline</span><span class="i-code">0xf0cd</span></div>
         <div class="the-icons span3" title="Code: 0xf0ce"><i class="demo-icon icon-table">&#xf0ce;</i> <span class="i-name">icon-table</span><span class="i-code">0xf0ce</span></div>
-        <div class="the-icons span3" title="Code: 0xf0f6"><i class="demo-icon icon-doc-text">&#xf0f6;</i> <span class="i-name">icon-doc-text</span><span class="i-code">0xf0f6</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf0f6"><i class="demo-icon icon-doc-text">&#xf0f6;</i> <span class="i-name">icon-doc-text</span><span class="i-code">0xf0f6</span></div>
         <div class="the-icons span3" title="Code: 0xf10d"><i class="demo-icon icon-quote-left">&#xf10d;</i> <span class="i-name">icon-quote-left</span><span class="i-code">0xf10d</span></div>
         <div class="the-icons span3" title="Code: 0xf114"><i class="demo-icon icon-folder-empty">&#xf114;</i> <span class="i-name">icon-folder-empty</span><span class="i-code">0xf114</span></div>
         <div class="the-icons span3" title="Code: 0xf121"><i class="demo-icon icon-code">&#xf121;</i> <span class="i-name">icon-code</span><span class="i-code">0xf121</span></div>
-        <div class="the-icons span3" title="Code: 0xf12b"><i class="demo-icon icon-superscript">&#xf12b;</i> <span class="i-name">icon-superscript</span><span class="i-code">0xf12b</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf12b"><i class="demo-icon icon-superscript">&#xf12b;</i> <span class="i-name">icon-superscript</span><span class="i-code">0xf12b</span></div>
         <div class="the-icons span3" title="Code: 0xf16a"><i class="demo-icon icon-youtube-play">&#xf16a;</i> <span class="i-name">icon-youtube-play</span><span class="i-code">0xf16a</span></div>
         <div class="the-icons span3" title="Code: 0xf1dc"><i class="demo-icon icon-header">&#xf1dc;</i> <span class="i-name">icon-header</span><span class="i-code">0xf1dc</span></div>
         <div class="the-icons span3" title="Code: 0xf1dd"><i class="demo-icon icon-paragraph">&#xf1dd;</i> <span class="i-name">icon-paragraph</span><span class="i-code">0xf1dd</span></div>

BIN
system/author/css/fontello/font/fontello.eot


+ 2 - 0
system/author/css/fontello/font/fontello.svg

@@ -44,6 +44,8 @@
 
 <glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
 
+<glyph glyph-name="bookmark-empty" unicode="&#xf097;" d="M643 707h-572v-693l237 227 49 47 50-47 236-227v693z m7 72q12 0 24-5 19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4-27 0-47 18l-246 236-246-236q-20-19-46-19-13 0-25 5-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" />
+
 <glyph glyph-name="list-bullet" unicode="&#xf0ca;" d="M214 64q0-44-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m0 286q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232v-107q0-7-5-13t-13-5h-678q-8 0-13 5t-5 13v107q0 7 5 12t13 6h678q7 0 13-6t5-12z m-786 518q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12v108q0 7 5 12t13 5h678q7 0 13-5t5-12z m0 285v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12v107q0 8 5 13t13 5h678q7 0 13-5t5-13z" horiz-adv-x="1000" />
 
 <glyph glyph-name="list-numbered" unicode="&#xf0cb;" d="M213-54q0-45-31-70t-75-26q-60 0-96 37l31 49q28-25 60-25 16 0 28 8t12 24q0 35-59 31l-14 31q4 6 18 24t24 31 20 21v1q-9 0-27-1t-27 0v-30h-59v85h186v-49l-53-65q28-6 45-27t17-49z m1 350v-89h-202q-4 20-4 30 0 29 14 52t31 38 37 27 31 24 14 25q0 14-9 22t-22 7q-25 0-45-32l-47 33q13 28 40 44t59 16q40 0 68-23t28-63q0-28-19-51t-42-36-42-28-20-30h71v34h59z m786-178v-107q0-7-5-13t-13-5h-678q-8 0-13 5t-5 13v107q0 8 5 13t13 5h678q7 0 13-6t5-12z m-786 502v-56h-187v56h60q0 22 0 67t1 68v7h-1q-5-10-28-30l-40 42 76 71h59v-225h60z m786-216v-108q0-7-5-12t-13-5h-678q-8 0-13 5t-5 12v108q0 7 5 12t13 5h678q7 0 13-5t5-12z m0 285v-107q0-7-5-12t-13-6h-678q-8 0-13 6t-5 12v107q0 8 5 13t13 5h678q7 0 13-5t5-13z" horiz-adv-x="1000" />

BIN
system/author/css/fontello/font/fontello.ttf


BIN
system/author/css/fontello/font/fontello.woff


BIN
system/author/css/fontello/font/fontello.woff2


+ 138 - 102
system/author/css/style.css

@@ -47,7 +47,7 @@ body,input,select,textarea{
 header, nav, h1, h2, h3, h4, h5, h6{
 	font-family: arial, sans-serif;
 }
-h1{ font-size: 1.8em; margin: 1em 0 0.8em; font-weight: 700: }
+h1{ font-size: 1.8em; margin: 1em 0 0.8em; font-weight: 700; }
 h2{ font-size: 1.6em; margin: 1em 0 0.8em; font-weight: 700; }
 h3{	font-size: 1em; margin: 0.6em 0 0.6em; text-transform: uppercase; font-weight: 300; }
 .main{
@@ -57,10 +57,10 @@ h3{	font-size: 1em; margin: 0.6em 0 0.6em; text-transform: uppercase; font-weigh
 }
 section{
 	background: #FFFFFF; 
-	box-shadow: 0 0 2px #ddd; 
+	box-shadow: 0 0 4px #ddd; 
 	position: relative;
 	margin-bottom: 40px;
-	padding: 20px 20px 40px;
+	padding: 20px 5px 40px;
 	box-sizing: border-box;
 }
 article{
@@ -84,7 +84,6 @@ aside.sidebar{
 .main-header{
 	display: inline-block;
 	width: 100%;
-	background: #fff;
 	border-bottom: 1px solid #eee;
 }
 .header-navi, .main{
@@ -124,13 +123,13 @@ aside.sidebar{
 	font-size: 0.9em;
 	text-transform: uppercase;
 	text-decoration: none;
-	margin: 0px 1px;
-	padding: 20px 10px 10px;
+	margin: 0px 5px;
+	padding: 20px 0px 10px 0px;
 	line-height: 2em;
 	border-bottom: 3px solid transparent;
 }
 .navi-items a:hover, .navi-items a:focus, .navi-items a:active, .navi-items a.active{
-	border-bottom: 3px solid #e0474c;
+	border-bottom: 3px solid #66b0a3;
 }
 .navi-items i{
 	color: #ddd;
@@ -138,9 +137,6 @@ aside.sidebar{
 .navi-items span{
 	display: none;
 }
-.navi-items a.active,.navi-items a.active i{
-	color: #e0474c;
-}
 
 /************************
 *  		MENU			*
@@ -192,15 +188,12 @@ li.menu-item{
 }
 .menu-item a:hover, .menu-item a:focus, .menu-item a:active, .menu-item a.active{
 	color: #fff;
-	background: #e0474c;
+	background: #70c1b3;
 }
 
 /********************
 *   CONTENT-NAVI	*
 ********************/
-.infoline{
-	display: none;
-}
 .content-navi{
 	background: transparent;
 	padding: 0;
@@ -215,32 +208,49 @@ li.menu-item{
 	padding: 0px;
 	position: relative;
 }
-.navi-item i.icon-doc-text, .navi-item i.icon-folder-empty, .navi-item i.icon-home, .navi-item i.icon-plus{
+.navi-item i.icon-doc-text, 
+.navi-item i.icon-folder-empty, 
+.navi-item i.icon-home, 
+.navi-item i.icon-plus{
 	display: inline-block;
 	position: absolute;
 	top: 0px;
-	background: #fff;
+	background: transparent;
 	color: #ccc;
 	padding: 7px 2px 7px;
 }
-.navi-item i.txt{
-	background: #e0474c;
-	color: #fff;
+.navi-item .status{
+	position: absolute;
+	width: 4px;
+	height: 100%;
+	left: -10px;
+	border-top: 1px solid #f9f8f6; 
+	border-bottom: 1px solid #f9f8f6;
 }
-.navi-item i.icon-resize-full-alt,.navi-item i.icon-move {
+.status.md{
+	background:#66b0a3;
+}
+.status.txt{
+	background:#cc4146;
+}
+.navi-item i.icon-resize-full-alt,
+.navi-item i.icon-move {
 	position: absolute;
 	right: 5px;
 	top: 7px;
-	color: #fff;
+	color: #f9f8f6;
+	color: #444;
+	background: transparent;
 }
 .navi-item a{
 	display: block;
 	padding: 7px 0;
 	width: 100%;
-	margin-bottom: 2px;
+	margin-bottom: 1px;
+	margin-top: 1px;
 	text-decoration: none;
 	color: #444;
-	background: #fff;
+	background: transparent;
 }
 .navi-item.folder a{
 	font-weight: 700;
@@ -248,13 +258,11 @@ li.menu-item{
 .navi-item.file a{
 	font-weight: 300;
 }
-.navi-item a:hover, .navi-item a:hover i{
-	background: #66b0a3;
-	color: #f9f8f6;
-}
+.navi-item a:focus, .navi-item a:focus i,
+.navi-item a:hover, .navi-item a:hover i,
 .navi-item a.active, .navi-item a.active i{
-	background: #e0474c;
-	color: #f9f8f6;
+	background:#66b0a3;
+	color: #fff;
 }
 [class^="level-"]{
 	padding-left: 80px;
@@ -297,7 +305,7 @@ a.addNaviLink:focus, a.addNaviLink:hover, a.addNaviLink:active{
 	box-sizing: border-box;
 	margin: 5px 0 10px;
 	padding: 5px;
-	background: #e0474c;
+	background:#66b0a3;
 	color: #f9f8f6;
 	width: 50%;
 	border: 0px;
@@ -307,7 +315,7 @@ a.addNaviLink:focus, a.addNaviLink:hover, a.addNaviLink:active{
 	width: 100%;
 }
 .addNaviForm button:hover{
-	background: #cc4146;
+	background: #4D978A;
 }
 .addNaviForm button.b-left{
 	border-right: 1px solid #f9f8f6;
@@ -353,16 +361,23 @@ footer{
 /********************
 *  	SETUP FORM 	    *
 ********************/
-
-.setupWrapper{
-	max-width: 300px;
-	margin-left: auto;
-	margin-right: auto;
-	margin-top: 8%;
+.authformWrapper{
+	width: 100%;
 	background: #fff;
 	padding: 40px;
-	border-radius: 3px;
 	box-shadow: 0px 0px 10px rgba(0,0,0,0.2);
+	border-radius: 3px;
+	box-sizing: border-box;
+}
+.setupContent{
+	width: 100%;
+	text-align: center;
+}
+.setupWrapper{
+	margin-top: 8%;
+	max-width: 350px;
+	margin-left: auto;
+	margin-right: auto;
 }
 .setupWrapper label{
 	font-weight: 700;
@@ -669,12 +684,12 @@ input[type="submit"]{
 	border-radius: 3px;
 	margin-bottom: 40px;
 	color: #f9f8f6;
-	border: 2px solid #e0474c; 
-	background: #e0474c; 
+	border: 2px solid #70c1b3; 
+	background: #70c1b3; 
 }
 input[type="submit"]:hover{				
-	border: 2px solid #cc4146; 
-	background: #cc4146; 
+	border: 2px solid #66b0a3; 
+	background: #66b0a3; 
 }
 input, select, button[type="button"]{
 	min-height: 52px;
@@ -732,14 +747,24 @@ button[type="button"].theme-button:hover{
 a.button, a.button:link,a.button:visited{
 	text-decoration: none;
 	color: #fff;
-	border: 2px solid #e0474c; 
-	background: #e0474c; 
+	border: 2px solid #70c1b3; 
+	background: #70c1b3; 
 }
 a.button:focus, a.button:hover, a.button:active{				
-	border: 2px solid #cc4146; 
-	background: #cc4146; 
+	border: 2px solid #66b0a3; 
+	background: #66b0a3; 
+}
+
+input[type="submit"].danger{
+	border: 2px solid #e0474c; 
+	background: #e0474c; 	
+}
+input[type="submit"].danger:hover{				
+border: 2px solid #cc4146; 
+background: #cc4146; 
 }
 
+
 .settings .medium a.button{
 	width: 100%;
 	display: block;
@@ -1259,7 +1284,7 @@ label .help, .label .help{
 	padding: 2px;
 	max-width: 900px;
 	background: #fff;
-	box-shadow: 0 0 2px #ddd;
+	box-shadow: 0 0 4px #ddd;
 	z-index: 99;
 }
 .buttonset .message.error{
@@ -1274,66 +1299,60 @@ label .help, .label .help{
 	box-sizing: border-box;
 	box-shadow: 0 0 2px #ddd;
 }
+
 .editor button, .editor a{
 	position: relative;
+	display: inline-block;
+	min-width: 40px;
+	margin: 4px 2px;
+	padding: 10px;
 	border-radius: 0px;
-	padding:10px;
-	min-width: 70px;
 	font-size: 0.8em;
-	margin: 4px 2px;
+	text-align: center;
+	text-decoration: none;
+	box-sizing: border-box;
+}
+.editor .secondary{
+	display: inline-block;
+	float: right;
+}
+.editor button.danger:enabled,
+.editor button.danger[enabled],
+.editor a.button--secondary,
+.editor a.button--secondary:visited{
+	border: 1px solid #eee;
+	background: #fff;
+	color: #444;
 }
 .editor button:enabled,
-.editor button[enabled]{
-	color: #f9f8f6;
-	border: 2px solid #e0474c; 
-	background: #e0474c; 
+.editor button[enabled],
+.editor a.button--secondary:focus,
+.editor a.button--secondary:hover,
+.editor a.button--secondary:active{
+	border: 1px solid #66b0a3; 
+	background: #66b0a3; 
+	color: #fff;
 }
 .editor button:enabled:hover,
 .editor button[enabled]:hover{
-	border: 2px solid #cc4146; 
-	background: #cc4146; 
+	border: 1px solid #4D978A; 
+	background: #4D978A;
+	color: #fff;
+}
+.editor button.danger:enabled:hover,
+.editor button.danger[enabled]:hover{
+	border: 1px solid #e0474c; 
+	background:#e0474c;
+	color: #fff;
 }
 .editor button:disabled,
 .editor button[disabled]{
-	border: 2px solid #eee;
-	background: #eee;
-	color: #444;
-	cursor: default;
-}
-.buttonset .secondary{
-	display: inline-block;
-	float: right;
-}
-.buttonset .secondary--block{
-	display: inline-block;
-}
-.editor button.button--secondary, .editor a.button--secondary{
-	display: inline-block;
-	min-width: auto;
-	max-width: 40px;
-	background: #fff;
 	border: 1px solid #eee;
-	color: #444;
-	text-decoration: none;
-}
-.editor button.button--secondary:hover, .editor a.button--secondary:hover, .editor a.button-secondary:focus, .editor a.button--secondary:active{
-	background: #e0474c;
-	border: 1px solid #e0474c;
-	color: #eee;
-}
-.editor button.button--secondary[disabled],
-.editor button.button--secondary:disabled{
-	border: 1px solid #f9f8f6; 
-	background: #f9f8f6;
+	background: #eee;
 	color: #444;
 	cursor: default;
 }
-.editor button.button--secondary__hightlight[enabled],
-.editor button.button--secondary__hightlight:enabled{
-	background: #66b0a3;
-	border: 1px solid #66b0a3;
-	color: #fff;
-}
+
 [v-cloak]{
 	display: none;
 }
@@ -1549,6 +1568,7 @@ button.hdown:hover,button.hdown:focus,button.hdown:active{
 .format-bar{
 	padding: 20px;
 	width:100%;
+	box-sizing: border-box;
 }
 .format-bar .editactive{
 	position: relative;
@@ -1600,7 +1620,7 @@ button.hdown:hover,button.hdown:focus,button.hdown:active{
   opacity: 0.3;
 }
 button.format-item{
-	margin-right: 2px;
+	margin: 2px 0;
 	padding: 5px;
 	background: #f9f8f6;
 	border: 1px solid #eee;
@@ -1968,19 +1988,25 @@ hr{
 	padding-left: 25px;	
 }
 .blox a, .blox a:link, .blox a:visited,
-footer a, footer a:link, footer a:visited
+footer a, footer a:link, footer a:visited,
+.setupContent a, .setupContent a:link, .setupContent a:visited
 { 
 	text-decoration: none; 
 	color: #e0474c; 
 }
 .blox a:focus, .blox a:hover, .blox a:active,
-footer a:focus, footer a:hover, footer a:active{ 
+footer a:focus, footer a:hover, footer a:active,
+.setupContent a:focus, .setupContent a:hover, .setupContent a:active
+{ 
 	text-decoration: underline;
 }
 .blox .TOC li:before{ color: #bbb; }
 
 
 @media only screen and (min-width: 600px) {
+	section{
+		padding: 20px 20px 40px;
+	}
 	header.headline{
 		padding: 0px 20px;
 	}
@@ -2080,18 +2106,12 @@ footer a:focus, footer a:hover, footer a:active{
 		background: #ccc; /* dot in the middle */
 		animation: spin 2s linear infinite;
 	}
-	
-	.buttonset .secondary--block{
-		display: inline-block;
-	}
 	.editor button.button--secondary, .editor a.button--secondary{
-		display: inline-block;
 		width: auto;
 		min-width: auto;
 		max-width: inherit;
-		border: 1px solid #eee;
-		color: #444;
 	}
+	
 	.mobile{
 		display: none;
 	}
@@ -2127,7 +2147,7 @@ footer a:focus, footer a:hover, footer a:active{
 	span.level-4{ padding-left: 50px; }
 	span.level-5{ padding-left: 65px; }
 	.navi-item i.icon-doc-text, .navi-item i.icon-folder-empty, .navi-item i.icon-home, .navi-item i.icon-plus{
-		left: -27px;
+		left: -24px;
 	}	
 	fieldset.plugin{
 		width: 49.5%;
@@ -2176,6 +2196,22 @@ footer a:focus, footer a:hover, footer a:active{
 	ul.menu-list{
 		margin: 5px 0 0 20px;
 	}
+	.navi-items a{
+		padding: 20px 5px 10px 0px;
+	}	
+	.navi-item .status{
+		left: -30px;
+	}	
+	.navi-item a i.icon-move, .navi-item a:link i.icon-move, .navi-item a:visited i.icon-move{
+		color: #f9f8f6;
+		background: transparent;
+	}
+	.navi-item a:focus, .navi-item a:focus i, .navi-item a:focus i.icon-move,
+	.navi-item a:hover, .navi-item a:hover i, .navi-item a:hover i.icon-move,
+	.navi-item a.active, .navi-item a.active i, .navi-item a.active i.icon-move{
+		background:#fff;
+		color: #444;
+	}	
 	.navi-items span{
 		display: inline;
 	}	

+ 25 - 23
system/author/editor/editor-blox.twig

@@ -32,17 +32,18 @@
 						<content-block :body="true" v-for="(block, index) in html" v-if="index !== 0">
 							<div v-if="block" class="blox" :key="block.id" @click.prevent="setData( $event )" :data-id="index" :id="'blox-' + index" v-html="block.html"></div>
 							<div v-else class="format-bar blox" @click.prevent="clearData( $event )" :data-id="index" :id="'blox-' + index">
-								<button class="format-item" @click.prevent="setData( $event, 'markdown-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-paragraph"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'headline-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-header"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'ulist-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-list-bullet"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'olist-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-list-numbered"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'image-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-picture"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'video-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-youtube-play"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'table-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-table"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'quote-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-quote-left"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'definition-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-colon"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'hr-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-minus"></i></button>
-								<button class="format-item" @click.prevent="setData( $event, 'code-component' )" :data-id="index" :id="'blox-' + index"><i class="icon-code"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'markdown-component' )" :data-id="index" :id="'blox-' + index" title="paragraph"><i class="icon-paragraph"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'headline-component' )" :data-id="index" :id="'blox-' + index" title="headline"><i class="icon-header"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'ulist-component' )" :data-id="index" :id="'blox-' + index" title="bullet list"><i class="icon-list-bullet"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'olist-component' )" :data-id="index" :id="'blox-' + index" title="numbered list"><i class="icon-list-numbered"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'image-component' )" :data-id="index" :id="'blox-' + index" title="image"><i class="icon-picture"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'video-component' )" :data-id="index" :id="'blox-' + index" title="youtube"><i class="icon-youtube-play"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'table-component' )" :data-id="index" :id="'blox-' + index" title="table"><i class="icon-table"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'quote-component' )" :data-id="index" :id="'blox-' + index" title="quote"><i class="icon-quote-left"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'definition-component' )" :data-id="index" :id="'blox-' + index" title="definition list"><i class="icon-colon"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'toc-component' )" :data-id="index" :id="'blox-' + index" title="table of contents"><i class="icon-list-alt"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'hr-component' )" :data-id="index" :id="'blox-' + index" title="horizontal line"><i class="icon-minus"></i></button>
+								<button class="format-item" @click.prevent="setData( $event, 'code-component' )" :data-id="index" :id="'blox-' + index" title="code block"><i class="icon-code"></i></button>
 							</div>
 						</content-block>
 					</draggable>
@@ -50,18 +51,19 @@
 	
 				<div class="format-bar">
 					<content-block :body="false">
-						<button class="format-item" @click.prevent="setData( $event, 'markdown-component' )" data-id="99999" id="blox-99999"><i class="icon-paragraph"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'headline-component' )" data-id="99999" id="blox-99999"><i class="icon-header"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'ulist-component' )" data-id="99999" id="blox-99999"><i class="icon-list-bullet"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'olist-component' )" data-id="99999" id="blox-99999"><i class="icon-list-numbered"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'image-component' )" data-id="99999" id="blox-99999"><i class="icon-picture"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'video-component' )" data-id="99999" id="blox-99999"><i class="icon-youtube-play"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'table-component' )" data-id="99999" id="blox-99999"><i class="icon-table"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'quote-component' )" data-id="99999" id="blox-99999"><i class="icon-quote-left"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'definition-component' )" data-id="99999" id="blox-99999"><i class="icon-colon"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'hr-component' )" data-id="99999" id="blox-99999"><i class="icon-minus"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'code-component' )" data-id="99999" id="blox-99999"><i class="icon-code"></i></button>
-				<!--	<button class="format-item" @click.prevent="setData( $event, 'math-component' )" data-id="99999" id="blox-99999"><i class="icon-math"></i></button>  -->
+						<button class="format-item" @click.prevent="setData( $event, 'markdown-component' )" data-id="99999" id="blox-99999" title="paragraph"><i class="icon-paragraph"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'headline-component' )" data-id="99999" id="blox-99999" title="headline"><i class="icon-header"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'ulist-component' )" data-id="99999" id="blox-99999" title="bullet list"><i class="icon-list-bullet"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'olist-component' )" data-id="99999" id="blox-99999" title="numbered list"><i class="icon-list-numbered"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'image-component' )" data-id="99999" id="blox-99999" title="image"><i class="icon-picture"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'video-component' )" data-id="99999" id="blox-99999" title="youtube"><i class="icon-youtube-play"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'table-component' )" data-id="99999" id="blox-99999" title="table"><i class="icon-table"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'quote-component' )" data-id="99999" id="blox-99999" title="quote"><i class="icon-quote-left"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'definition-component' )" data-id="99999" id="blox-99999" title="definition list"><i class="icon-colon"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'toc-component' )" data-id="99999" id="blox-99999" title="table of contents"><i class="icon-list-alt"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'hr-component' )" data-id="99999" id="blox-99999" title="horizontal line"><i class="icon-minus"></i></button>
+						<button class="format-item" @click.prevent="setData( $event, 'code-component' )" data-id="99999" id="blox-99999" title="code block"><i class="icon-code"></i></button>
+				<!--	<button class="format-item" @click.prevent="setData( $event, 'math-component' )" data-id="99999" id="blox-99999" title="math"><i class="icon-math"></i></button>  -->
 					</content-block>
 				</div>
 				

+ 18 - 24
system/author/editor/publish-controller.twig

@@ -1,27 +1,21 @@
-<div class="editor">
-	<div class="buttonset" id="publishController" data-published="{{ item.published }}" data-drafted="{{ item.drafted }}">
-		<div id="publishController"  v-cloak>
-			<div v-if="errors.message" class="message error">${ errors.message }</div>
-			<button v-if="raw" @click.prevent="saveDraft" id="draft" :class="draftResult" :disabled="draftDisabled"><span class="desktop">Save&nbsp;</span>Draft</button><button @click.prevent="publishDraft" id="publish" :class="publishResult" :disabled="publishDisabled">Publish</button>
-			<div class="secondary">
-				<div class="secondary--block">
-					<button @click.prevent="depublishArticle" class="button--secondary button--secondary__hightlight" :disabled="publishStatus"><span class="desktop">${publishLabel}</span><span class="mobile">ON</span></button>
-					<a v-if="visual" href="{{ base_url }}/tm/content/raw{{item.urlRelWoF}}" class="button--secondary"><span class="desktop">raw mode</span><span class="mobile">raw</span></a>
-					<a v-if="raw" href="{{ base_url }}/tm/content/visual{{item.urlRelWoF}}" class="button--secondary"><span class="desktop">visual mode</span><span class="mobile">visual</span></a>
-					<button @click.prevent="showModal" class="button--secondary"><span class="desktop">delete</span><span class="mobile">X</span></button>
-					<a target="_blank" class="button--secondary" href="{{ item.urlAbs }}"><i class="icon-link-ext"></i></a>
-				</div>
+<div class="editor buttonset" id="publishController" data-published="{{ item.published }}" data-drafted="{{ item.drafted }}" v-cloak>
+	<div v-if="errors.message" class="message error">${ errors.message }</div>
+	<button v-if="raw" @click.prevent="saveDraft" id="draft" :class="draftResult" :disabled="draftDisabled"><span class="desktop">Save&nbsp;</span>Draft</button><button @click.prevent="publishDraft" id="publish" :class="publishResult" :disabled="publishDisabled">Publish</button>
+	<div class="secondary">
+		<button @click.prevent="depublishArticle" class="button--secondary" :disabled="publishStatus"><span class="desktop">${publishLabel}</span><span class="mobile">${publishLabelMobile}</span></button>
+		<button @click.prevent="showModal" class="button--secondary danger"><span class="desktop">delete</span><span class="mobile">X</span></button>
+		<a v-if="visual" href="{{ base_url }}/tm/content/raw{{item.urlRelWoF}}" class="button--secondary"><span class="desktop">raw mode</span><span class="mobile">raw</span></a>
+		<a v-if="raw" href="{{ base_url }}/tm/content/visual{{item.urlRelWoF}}" class="button--secondary"><span class="desktop">visual mode</span><span class="mobile">visual</span></a>
+		<a target="_blank" class="button--secondary" href="{{ item.urlAbs }}"><i class="icon-link-ext"></i></a>
+	</div>
+	<transition name="fade">
+		<div v-if="modalWindow" id="modalWindow" class="modalWindow">
+			<div class="modalInner">
+				<div @click="hideModal" id="closeModal" class="closeModal">X</div>
+				<h2>Delete page</h2>
+				<p>Do you really want to delete this page? Please confirm.</p>
+				<button @click.prevent="deleteArticle" class="large danger" :class="deleteResult" :disabled="deleteDisabled">Delete Page</button>
 			</div>
-			<transition name="fade">
-				<div v-if="modalWindow" id="modalWindow" class="modalWindow">
-					<div class="modalInner">
-						<div @click="hideModal" id="closeModal" class="closeModal">X</div>
-						<h2>Delete page</h2>
-						<p>Do you really want to delete this page? Please confirm.</p>
-						<button @click.prevent="deleteArticle" class="large" :class="deleteResult" :disabled="deleteDisabled">Delete Page</button>
-					</div>
-				</div>
-			</transition>
 		</div>
-	</div>
+	</transition>
 </div>

+ 40 - 5
system/author/js/vue-blox.js

@@ -272,7 +272,7 @@ const contentComponent = Vue.component('content-block', {
 							{
 								self.$root.$data.markdown.push(result.markdown);
 								self.$root.$data.html.push(result.content);
-								
+
 								self.$root.$data.blockMarkdown = '';
 								self.$root.$data.blockType = 'markdown-component';
 								self.getData();
@@ -282,6 +282,7 @@ const contentComponent = Vue.component('content-block', {
 							else if(self.$root.$data.newblock)
 							{
 								self.$root.$data.html.splice(result.id,1,result.content);
+								self.$root.$data.html.splice(result.toc.id,1,result.toc);
 								self.$root.$data.markdown[result.id] = result.markdown;								
 
 								self.$root.$data.blockMarkdown = '';
@@ -296,12 +297,16 @@ const contentComponent = Vue.component('content-block', {
 								self.$root.$data.html.splice(result.id,1,result.content);
 
 								if(result.id == 0){ self.$root.$data.title = result.content; }
-								
-								// document.getElementById('blox-'+result.id).innerHTML = result.content;
-								
+
 								self.$root.$data.blockMarkdown = '';
 								self.$root.$data.blockType = '';
 							}
+
+							/* update the table of content if in result */
+							if(result.toc)
+							{
+								self.$root.$data.html.splice(result.toc.id, 1, result.toc);
+							}
 						}
 					}
 					else if(httpStatus != 200)
@@ -356,6 +361,12 @@ const contentComponent = Vue.component('content-block', {
 						self.$root.$data.markdown.splice(bloxid,1);
 						self.$root.$data.blockMarkdown = '';
 						self.$root.$data.blockType = '';
+
+						/* update the table of content if in result */
+						if(result.toc)
+						{
+							self.$root.$data.html.splice(result.toc.id, 1, result.toc);
+						}
 					}
 				}
 			}, method, url, params);
@@ -415,6 +426,25 @@ const hrComponent = Vue.component('hr-component', {
 	},
 })
 
+const tocComponent = Vue.component('toc-component', {
+	props: ['compmarkdown', 'disabled'],
+	template: '<div>' + 
+				'<div class="contenttype"><i class="icon-paragraph"></i></div>' +
+				'<textarea class="mdcontent" ref="markdown" :value="compmarkdown" :disabled="disabled" @input="updatemarkdown">---</textarea>' +
+				'</div>',
+	mounted: function(){
+		this.$refs.markdown.focus();
+		autosize(document.querySelectorAll('textarea'));
+		this.$emit('updatedMarkdown', '[TOC]');
+	},
+	methods: {
+		updatemarkdown: function(event)
+		{
+			this.$emit('updatedMarkdown', event.target.value);
+		},
+	},
+})
+
 const codeComponent = Vue.component('code-component', {
 	props: ['compmarkdown', 'disabled'],
 	template: '<div>' + 
@@ -1235,6 +1265,7 @@ let editor = new Vue({
 		'content-component': contentComponent,
 		'markdown-component': markdownComponent,
 		'hr-component': hrComponent,
+		'toc-component': tocComponent,
 		'title-component': titleComponent,
 		'headline-component': headlineComponent,
 		'image-component': imageComponent,
@@ -1361,13 +1392,17 @@ let editor = new Vue({
 					}
 					else
 					{
-
 						self.freeze = false;
 
 						self.markdown = result.markdown;
 						self.blockMarkdown = '';
 						self.blockType = '';
 
+						if(result.toc)
+						{
+							self.html.splice(result.toc.id, 1, result.toc);
+						}
+						
 						publishController.publishDisabled = false;
 						publishController.publishResult = "";
 					}

+ 1 - 1
system/author/js/vue-navi.js

@@ -33,7 +33,7 @@ const navcomponent = Vue.component('navigation', {
 				'parent_id_to': 	evt.to.parentNode.id, 
 				'index_old': 		evt.oldIndex,
 				'index_new': 		evt.newIndex,
-				'active':			evt.item.firstChild.className,
+				'active':			evt.item.getElementsByTagName('a')[0].className,
 				'url':				document.getElementById("path").value,
 				'csrf_name': 		document.getElementById("csrf_name").value,
 				'csrf_value':		document.getElementById("csrf_value").value,				

+ 3 - 0
system/author/js/vue-publishcontroller.js

@@ -22,6 +22,7 @@ let publishController = new Vue({
 		deleteResult: "",
 		publishStatus: document.getElementById("publishController").dataset.published ? false : true,
 		publishLabel: document.getElementById("publishController").dataset.published ? "online" : "offline",
+		publishLabelMobile: document.getElementById("publishController").dataset.published ? "ON" : "OFF",
 		raw: false,
 		visual: false,
 	},
@@ -70,6 +71,7 @@ let publishController = new Vue({
 						self.publishResult = "success";
 						self.publishStatus = false;
 						self.publishLabel = "online";
+						self.publishLabelMobile = "ON";
 					}
 				}
 				else if(httpStatus != 200)
@@ -173,6 +175,7 @@ let publishController = new Vue({
 					{
 						self.publishResult = "";
 						self.publishLabel = "offline";
+						self.publishLabelMobile = "OFF";
 						self.publishDisabled = false;
 					}
 				}

+ 3 - 19
system/author/partials/editorNavi.twig

@@ -2,7 +2,6 @@
 	<div id="data-navi" data-navi='{{ navigation|json_encode() }}' data-editormode="{{settings.editor}}"></div>
 	<div id="mobile-menu" class="menu-action">Menu <span class="button-arrow"></span></div>
 	<div id="navi" class="content-navi" v-model="freeze" v-cloak>
-		<div class="infoline">Reorder navi with drag&drop<div class="help"  @click="showModal">?</div></div>
 		<div class="navi-list">
 			<div class="navi-item folder">
 				<a href="{{ base_url }}/tm/content/{{ settings.editor }}"><i class="icon-home"></i><span class="level-1">Homepage</span></a>
@@ -20,29 +19,14 @@
 				</div>
 			</li>
 		</ul>
-		<transition name="fade">
-			<div v-if="modalWindow" id="modalWindow" class="modalWindow">
-				<div class="modalInner wide">
-					<div @click="hideModal" id="closeModal" class="closeModal">X</div>
-					<h2>Reorder The Navigation</h2>
-					<p>You can reorder the navigation with simple drag&drop. However, there are some rules and limitations:</p>
-					<ul>
-						<li>You can move <strong>files</strong> to any other <strong>folder</strong>.</li>
-						<li>Only <strong>folders</strong> are allowed at the <strong>first level</strong>.</li>
-						<li><strong>Folders</strong> can be reordered within the <strong>same level</strong>.</li>
-						<li>But a <strong>folder</strong> can not be moved to another folder or <strong>another level</strong>.</li>
-					</ul>
-					<p>Here is the reason for the last restriction: If you move a folder to another folder, then the adress (url) will change for the whole folder and all its content (pages). It is a nightmare for your readers and for google.</p>
-					<p>If you really want to move the whole folder content, then create a new folder in the desired place and move all files manually to the new folder.</p>
-				</div>
-			</div>
-		</transition>
 	</div>
 </nav>
 
 {% verbatim %}
 	<template id="navigation-template">
-		<li class="navi-item" :class="elementtype"><a v-bind:href="getUrl(root, url)" :class="checkActive(active,parent)"><i :class="getIcon(elementtype, filetype)"></i><span :class="getLevel(level)">{{ name }}</span><i class="icon-move"></i></a>
+		<li class="navi-item" :class="elementtype">
+			<div class="status" :class="filetype"></div>
+			<a v-bind:href="getUrl(root, url)" :class="checkActive(active,parent)"><i :class="getIcon(elementtype, filetype)"></i><span :class="getLevel(level)">{{ name }}</span><i class="icon-move"></i></a>
 			<draggable v-if="folder" :element="'ul'" class="navi-list" :list="folder" :move="checkMove" @start="onStart" @end="onEnd" :options="{group:{ name:'file'}, animation: 150, 'disabled': freeze }">
 				<navigation ref="draggit" v-for="item in folder" :freeze="freeze" :name="item.name" :active="item.active" :parent="item.activeParent" :level="item.keyPath" :url="item.urlRelWoF" :root="root" v-bind:id="item.keyPath" :key="item.keyPath" :filetype="item.fileType" :elementtype="item.elementType" :folder="item.folderContent"></navigation>
 			</draggable>

+ 2 - 2
system/author/settings/user.twig

@@ -65,7 +65,7 @@
 				</fieldset>
 
 			</section>
-			<input type="submit" value="Save User" />
+			<input type="submit" value="Update User" />
 
 			{{ csrf_field() | raw }}
 			<div class="actionLink">
@@ -81,7 +81,7 @@
 				<h2>Delete {{ userdata.username }}</h2>
 				<p>Do you really want to delete the user {{userdata.username}}? Please confirm.</p>
 				<input type="hidden" name="username" value="{{userdata.username}}">
-				<input type="submit" value="Delete user">
+				<input type="submit" class="danger" value="Delete user">
 				{{ csrf_field() | raw }}
 			</form>
 		</div>

+ 18 - 0
system/system.php

@@ -4,6 +4,14 @@ use Typemill\Events\OnSettingsLoaded;
 use Typemill\Events\OnPluginsLoaded;
 use Typemill\Events\OnSessionSegmentsLoaded;
 
+/****************************
+* HIDE ERRORS BY DEFAULT	  *
+****************************/
+
+ini_set('display_errors', 0);
+ini_set('display_startup_errors', 0);
+error_reporting(E_ALL);
+
 /****************************
 * CREATE EVENT DISPATCHER	*
 ****************************/
@@ -16,6 +24,16 @@ $dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
 
 $settings = Typemill\Settings::loadSettings();
 
+/****************************
+* HANDLE DISPLAY ERRORS 	  *
+****************************/
+
+if($settings['settings']['displayErrorDetails'])
+{
+	ini_set('display_errors', 1);
+	ini_set('display_startup_errors', 1);	
+}
+
 /************************
 * INITIATE SLIM 		*
 ************************/

Некоторые файлы не были показаны из-за большого количества измененных файлов