Pārlūkot izejas kodu

Version 1.2.11: Table editor

Sebastian 6 gadi atpakaļ
vecāks
revīzija
f40622ed2c
36 mainītis faili ar 525 papildinājumiem un 121 dzēšanām
  1. 1 1
      cache/lastCache.txt
  2. 0 0
      content/00-Welcome/01-Write-Content.md
  3. 0 0
      content/00-Welcome/02-Get-Help.md
  4. 0 0
      content/00-Welcome/03-Markdown-Test.md
  5. BIN
      media/live/5c4ccd43e5ac8-live.png
  6. BIN
      media/live/5c4ccd43e5ac8-mlibrary.png
  7. BIN
      media/original/5c4ccd43e5ac8-original.png
  8. 9 1
      system/Controllers/ContentController.php
  9. 2 2
      system/Controllers/SettingsController.php
  10. 1 1
      system/Models/Fields.php
  11. 1 1
      system/Models/Validation.php
  12. 2 2
      system/Models/Write.php
  13. 1 1
      system/author/auth/welcome.twig
  14. 46 3
      system/author/css/style.css
  15. 2 2
      system/author/editor/editor-blox.twig
  16. 257 9
      system/author/js/vue-blox.js
  17. 4 1
      system/author/js/vue-editor.js
  18. 3 3
      system/author/js/vue-navi.js
  19. 55 22
      system/author/js/vue-publishcontroller.js
  20. 14 1
      system/author/settings/plugins.twig
  21. 37 25
      themes/typemill/css/fontello/config.json
  22. 5 3
      themes/typemill/css/fontello/css/fontello-codes.css
  23. 3 3
      themes/typemill/css/fontello/css/fontello-embedded.css
  24. 5 3
      themes/typemill/css/fontello/css/fontello-ie7-codes.css
  25. 5 3
      themes/typemill/css/fontello/css/fontello-ie7.css
  26. 12 10
      themes/typemill/css/fontello/css/fontello.css
  27. 12 10
      themes/typemill/css/fontello/demo.html
  28. BIN
      themes/typemill/css/fontello/font/fontello.eot
  29. 8 4
      themes/typemill/css/fontello/font/fontello.svg
  30. BIN
      themes/typemill/css/fontello/font/fontello.ttf
  31. BIN
      themes/typemill/css/fontello/font/fontello.woff
  32. BIN
      themes/typemill/css/fontello/font/fontello.woff2
  33. 3 0
      themes/typemill/css/style.css
  34. 8 3
      themes/typemill/page.twig
  35. 5 5
      themes/typemill/partials/navigation.twig
  36. 24 2
      themes/typemill/typemill.yaml

+ 1 - 1
cache/lastCache.txt

@@ -1 +1 @@
-1548495240
+1550398193

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


+ 0 - 0
content/00-Welcome/03-Get-Help.md → content/00-Welcome/02-Get-Help.md


+ 0 - 0
content/00-Welcome/04-markdown-test.md → content/00-Welcome/03-Markdown-Test.md


BIN
media/live/5c4ccd43e5ac8-live.png


BIN
media/live/5c4ccd43e5ac8-mlibrary.png


BIN
media/original/5c4ccd43e5ac8-original.png


+ 9 - 1
system/Controllers/ContentController.php

@@ -92,8 +92,10 @@ abstract class ContentController
 		$vResult = $validate->editorInput($this->params);
 		$vResult = $validate->editorInput($this->params);
 		
 		
 		if(is_array($vResult))
 		if(is_array($vResult))
-		{ 
+		{
+			$message = reset($vResult);
 			$this->errors = ['errors' => $vResult];
 			$this->errors = ['errors' => $vResult];
+			if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
 			return false;
 			return false;
 		}
 		}
 		return true;
 		return true;
@@ -106,7 +108,9 @@ abstract class ContentController
 		
 		
 		if(is_array($vResult))
 		if(is_array($vResult))
 		{ 
 		{ 
+			$message = reset($vResult);
 			$this->errors = ['errors' => $vResult];
 			$this->errors = ['errors' => $vResult];
+			if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
 			return false;
 			return false;
 		}
 		}
 		return true;
 		return true;
@@ -119,7 +123,9 @@ abstract class ContentController
 		
 		
 		if(is_array($vResult))
 		if(is_array($vResult))
 		{
 		{
+			$message = reset($vResult);
 			$this->errors = ['errors' => $vResult];
 			$this->errors = ['errors' => $vResult];
+			if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
 			return false;
 			return false;
 		}
 		}
 		return true;
 		return true;
@@ -132,7 +138,9 @@ abstract class ContentController
 		
 		
 		if(is_array($vResult))
 		if(is_array($vResult))
 		{
 		{
+			$message = reset($vResult);
 			$this->errors = ['errors' => $vResult];
 			$this->errors = ['errors' => $vResult];
+			if(isset($message[0])){ $this->errors['errors']['message'] = $message[0]; }
 			return false;
 			return false;
 		}
 		}
 		return true;
 		return true;

+ 2 - 2
system/Controllers/SettingsController.php

@@ -114,7 +114,7 @@ class SettingsController extends Controller
 						
 						
 			if(isset($themeSettings['forms']['fields']))
 			if(isset($themeSettings['forms']['fields']))
 			{
 			{
-				$fields = $fieldsModel->getFields($userSettings, 'themes', $themeName, $themeSettings);
+				$fields = $fieldsModel->getFields($userSettings, 'themes', $themeName, $themeSettings);				
 								
 								
 				/* overwrite original theme form definitions with enhanced form objects */
 				/* overwrite original theme form definitions with enhanced form objects */
 				$themedata[$themeName]['forms']['fields'] = $fields;
 				$themedata[$themeName]['forms']['fields'] = $fields;
@@ -193,7 +193,7 @@ class SettingsController extends Controller
 				$fields = $fieldsModel->getFields($userSettings, 'plugins', $pluginName, $pluginOriginalSettings);
 				$fields = $fieldsModel->getFields($userSettings, 'plugins', $pluginName, $pluginOriginalSettings);
 				
 				
 				/* overwrite original plugin form definitions with enhanced form objects */
 				/* overwrite original plugin form definitions with enhanced form objects */
-				$plugins[$pluginName]['forms']['fields'] = $fields;				
+				$plugins[$pluginName]['forms']['fields'] = $fields;			
 			}
 			}
 		}
 		}
 		
 		

+ 1 - 1
system/Models/Fields.php

@@ -13,7 +13,7 @@ class Fields
 
 
 		# formtype are backend forms or public forms, only relevant for plugins for now
 		# formtype are backend forms or public forms, only relevant for plugins for now
 		$formType = $formType ? $formType : 'forms';
 		$formType = $formType ? $formType : 'forms';
-
+		
 		# iterate through all fields of the objectSetting (theme or plugin)
 		# iterate through all fields of the objectSetting (theme or plugin)
 		foreach($objectSettings[$formType]['fields'] as $fieldName => $fieldConfigurations)
 		foreach($objectSettings[$formType]['fields'] as $fieldName => $fieldConfigurations)
 		{
 		{

+ 1 - 1
system/Models/Validation.php

@@ -285,7 +285,7 @@ class Validation
 		$v->rule('required', ['folder_id', 'item_name', 'type', 'url']);
 		$v->rule('required', ['folder_id', 'item_name', 'type', 'url']);
 		$v->rule('regex', 'folder_id', '/^[0-9.]+$/i');
 		$v->rule('regex', 'folder_id', '/^[0-9.]+$/i');
 		$v->rule('noSpecialChars', 'item_name');
 		$v->rule('noSpecialChars', 'item_name');
-		$v->rule('lengthBetween', 'item_name', 1, 20);
+		$v->rule('lengthBetween', 'item_name', 1, 40);
 		$v->rule('in', 'type', ['file', 'folder']);
 		$v->rule('in', 'type', ['file', 'folder']);
 		
 		
 		if($v->validate()) 
 		if($v->validate()) 

+ 2 - 2
system/Models/Write.php

@@ -24,7 +24,7 @@ class Write
 			}
 			}
 			else
 			else
 			{
 			{
-				throw new \Exception("The folder '{$folder}' is missing and we could not create it. Please create the folder manually on your server.");
+#				throw new \Exception("The folder '{$folder}' is missing and we could not create it. Please create the folder manually on your server.");
 				return false;				
 				return false;				
 			}
 			}
 		}
 		}
@@ -35,7 +35,7 @@ class Write
 		}
 		}
 		else
 		else
 		{
 		{
-			throw new \Exception("Please make the folder '{$folder}' writable.");
+#			throw new \Exception("Please make the folder '{$folder}' writable.");
 			return false;
 			return false;
 		}
 		}
 		return true;
 		return true;

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

@@ -11,7 +11,7 @@
 				<h1>Hurra!</h1>
 				<h1>Hurra!</h1>
 				<p>Your account has been created and you are logged in now.</p>
 				<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>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> We recently added many format options like images, youtube videos, list and codeblocks to the visual content editor.</p>
+				<p><strong>New:</strong>Markdown is cool but editing tables is a nightmare. But not with Typemill, because we added a visual table editor recently. Try it!</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>
 				<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>
 			</div>
 			<a class="button" href="{{ path_for('settings.show') }}">Configure your website</a>
 			<a class="button" href="{{ path_for('settings.show') }}">Configure your website</a>

+ 46 - 3
system/author/css/style.css

@@ -1567,11 +1567,54 @@ button.format-item:hover{
 	font-weight: 700;
 	font-weight: 700;
 }
 }
 .blox tbody{}
 .blox tbody{}
-.blox tr{}
-.blox tr:nth-child(odd){ }
+.blox th{ padding: 10px 0;}
+.blox tr,.blox-editor tr{}
+.blox tr:nth-child{ }
 .blox tr:nth-child(even){ background-color:#f9f8f6; }
 .blox tr:nth-child(even){ background-color:#f9f8f6; }
 .blox td{ padding: 5px;}
 .blox td{ padding: 5px;}
-.blox th{ padding: 10px 0;}
+
+.blox-editor table{ 
+	display: inline-table;
+	width: 100%;  
+	border-collapse: collapse; 
+	margin-bottom: 20px;
+}
+.blox-editor thead{}
+.blox-editor tbody{}
+.blox-editor tr{}
+.blox-editor th{ border: 1px solid #ccc; padding: 5px; }
+.blox-editor td{ border: 1px solid #ccc; padding: 5px; }
+.blox-editor td.noteditable, .blox-editor th.noteditable{ 
+	border: 1px solid #ccc; 
+	text-align:center; 
+	color: #ccc; 
+	background: #f9f8f6; 
+	font-weight: 300;
+	padding: 0;
+}
+.blox-editor .columnaction, .blox-editor .rowaction{
+	position: absolute;
+	background: #fff;
+	width: 150px;
+	font-size: 0.9em;
+	color: #000;
+	text-align: left;
+	box-shadow: 0 0 2px #000;
+	margin: 5px;
+	z-index:999999;
+}
+.blox-editor .rowaction{
+	margin-left: 53px;
+	margin-top: -3px;
+}
+.blox-editor .actionline{
+	padding: 5px 10px;
+	cursor: pointer;
+}
+.blox-editor .actionline:hover{
+	background: #70c1b3;
+	color: #fff;
+}
 .blox dl{
 .blox dl{
 	border-top: 1px solid #e0474c;
 	border-top: 1px solid #e0474c;
 	border-bottom: 1px solid #e0474c;
 	border-bottom: 1px solid #e0474c;

+ 2 - 2
system/author/editor/editor-blox.twig

@@ -33,10 +33,10 @@
 						<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, '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, '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, '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, 'quote-component' )" data-id="99999" id="blox-99999"><i class="icon-quote-left"></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, 'code-component' )" data-id="99999" id="blox-99999"><i class="icon-code"></i></button>
-				<!--	<button class="format-item" @click.prevent="setData( $event, 'code-component' )" data-id="99999" id="blox-99999"><i class="icon-table"></i></button>
-						<button class="format-item" @click.prevent="setData( $event, 'code-component' )" data-id="99999" id="blox-99999"><i class="icon-math"></i></button>  -->
+				<!--	<button class="format-item" @click.prevent="setData( $event, 'code-component' )" data-id="99999" id="blox-99999"><i class="icon-math"></i></button>  -->
 					</content-block>
 					</content-block>
 				</div>
 				</div>
 				
 				

+ 257 - 9
system/author/js/vue-blox.js

@@ -162,7 +162,7 @@ const contentComponent = Vue.component('content-block', {
 			}
 			}
 		},
 		},
 		saveBlock: function()
 		saveBlock: function()
-		{
+		{			
 			if(this.compmarkdown == undefined || this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"") == '')
 			if(this.compmarkdown == undefined || this.compmarkdown.replace(/(\r\n|\n|\r|\s)/gm,"") == '')
 			{
 			{
 				this.switchToPreviewMode();	
 				this.switchToPreviewMode();	
@@ -203,17 +203,17 @@ const contentComponent = Vue.component('content-block', {
 					if(httpStatus == 400)
 					if(httpStatus == 400)
 					{
 					{
 						self.activatePage();
 						self.activatePage();
-						publishController.errors.message = "Sorry, something went wrong. Maybe you are logged out? Please login and try again.";
+						publishController.errors.message = "Looks like you are logged out. Please login and try again.";
 					}
 					}
-					if(response)
+					else if(response)					
 					{
 					{
 						self.activatePage();
 						self.activatePage();
-						
+
 						var result = JSON.parse(response);
 						var result = JSON.parse(response);
-																	
+										
 						if(result.errors)
 						if(result.errors)
 						{
 						{
-							publishController.errors.message = result.errors.markdown[0];
+							publishController.errors.message = result.errors.message;
 						}
 						}
 						else
 						else
 						{
 						{
@@ -227,7 +227,8 @@ const contentComponent = Vue.component('content-block', {
 								self.$root.$data.blockMarkdown = '';
 								self.$root.$data.blockMarkdown = '';
 								self.$root.$data.blockType = 'markdown-component';
 								self.$root.$data.blockType = 'markdown-component';
 								self.getData();
 								self.getData();
-								document.querySelectorAll('textarea')[0].style.height = "70px";
+								var textbox = document.querySelectorAll('textarea')[0];
+								if(textbox){ textbox.style.height = "70px"; }
 							}
 							}
 							else
 							else
 							{
 							{
@@ -241,6 +242,11 @@ const contentComponent = Vue.component('content-block', {
 							}
 							}
 						}
 						}
 					}
 					}
+					else if(httpStatus != 200)
+					{
+						self.activatePage();
+						publishController.errors.message = "Sorry, something went wrong. Please refresh the page and try again.";
+					}					
 				}, method, url, params);
 				}, method, url, params);
 			}
 			}
 		},
 		},
@@ -430,6 +436,28 @@ const ulistComponent = Vue.component('ulist-component', {
 		{
 		{
 			this.compmarkdown = '* ';
 			this.compmarkdown = '* ';
 		}
 		}
+		else
+		{
+			var lines = this.compmarkdown.split("\n");
+			var length = lines.length
+			var md = '';
+
+			for(i = 0; i < length; i++)
+			{
+				var clean = lines[i];
+				clean = clean.replace(/^- /, '* ');
+				clean = clean.replace(/^\+ /, '* ');
+				if(i == length-1)
+				{
+					md += clean;
+				}
+				else
+				{
+					md += clean + '\n';
+				}
+			}
+			this.compmarkdown = md;
+		}
 		this.$nextTick(function () {
 		this.$nextTick(function () {
 			autosize(document.querySelectorAll('textarea'));
 			autosize(document.querySelectorAll('textarea'));
 		});	
 		});	
@@ -487,6 +515,219 @@ const headlineComponent = Vue.component('headline-component', {
 	},
 	},
 })
 })
 
 
+const tableComponent = Vue.component('table-component', { 
+	props: ['compmarkdown', 'disabled'],
+	data: function(){
+		return {
+			table: [
+				['0', '1', '2'],
+				['1', 'Head', 'Head'],
+				['2', 'cell', 'cell'],
+				['3', 'cell', 'cell'],
+			],
+			editable: 'editable',
+			noteditable: 'noteditable',
+			cellcontent: '',
+			columnbar: false,
+			rowbar: false,
+			tablekey: 1,
+		}
+	},
+	template: '<div ref="table" :key="tablekey">' + 
+				'<div class="contenttype"><i class="icon-table"></i></div>' +
+				'<table ref="markdown">' +
+					'<colgroup>' +
+						'<col v-for="col in table[0]">' +
+					'</colgroup>' +
+					'<tbody>' +
+						'<tr v-for="(row, rowindex) in table">' +
+							'<td v-if="rowindex === 0" v-for="(value,colindex) in row" contenteditable="false" class="noteditable" @click="switchcolumnbar(value)">{{value}} ' +
+							  '<div v-if="columnbar === value" class="columnaction">' + 
+							     '<div class="actionline" @click="addrightcolumn(value)">add right column</div>' +
+								 '<div class="actionline" @click="addleftcolumn(value)">add left column</div>' +
+								 '<div class="actionline" @click="deletecolumn(value)">delete column</div>' +
+							  '</div>' +
+							'</td>' +
+							'<th v-if="rowindex === 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
+							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
+							     '<div class="actionline" @click="addaboverow(value)">add row above</div>' +
+								 '<div class="actionline" @click="addbelowrow(value)">add row below</div>' +
+								 '<div class="actionline" @click="deleterow(value)">delete row</div>' +
+							  '</div>' + 
+							'{{value}}</th>' +
+							'<td v-if="rowindex > 1" v-for="(value,colindex) in row" :contenteditable="colindex !== 0 ? true : false" @click="switchrowbar(value)" @blur="updatedata($event,colindex,rowindex)" :class="colindex !== 0 ? editable : noteditable">' + 
+							 '<div v-if="colindex === 0 && rowbar === value" class="rowaction">' + 
+							     '<div class="actionline" @click="addaboverow(value)">add row above</div>' +
+								 '<div class="actionline" @click="addbelowrow(value)">add row below</div>' +
+								 '<div class="actionline" @click="deleterow(value)">delete row</div>' +
+							  '</div>' +
+							'{{ value }}</td>' +
+						'</tr>' +
+					'</tbody>' +
+				'</table>' +
+				'</div>',
+	mounted: function(){
+		this.$refs.markdown.focus();
+		if(this.compmarkdown)
+		{
+			var table = [];
+			var lines = this.compmarkdown.split("\n");
+			var length = lines.length
+			var c = 1;
+			
+			for(i = 0; i < length; i++)
+			{
+				if(i == 1){ continue }
+				
+				var line = lines[i].trim();
+				var row = line.split("|").map(function(cell){
+					return cell.trim();
+				});
+				if(row[0] == ''){ row.shift() }
+				if(row[row.length-1] == ''){ row.pop() }
+				if(i == 0)
+				{
+					var rlength = row.length;
+					var row0 = [];
+					for(y = 0; y <= rlength; y++) { row0.push(y) }
+					table.push(row0);
+				}
+				row.splice(0,0,c);
+				c++;
+				table.push(row);
+			}
+			this.table = table;
+		}
+	},
+	methods: {
+		updatedata: function(event,col,row)
+		{
+			this.table[row][col] = event.target.innerText;			
+			this.markdowntable();
+		},
+		switchcolumnbar(value)
+		{
+			this.rowbar = false;
+			(this.columnbar == value || value == 0) ? this.columnbar = false : this.columnbar = value;
+		},
+		switchrowbar(value)
+		{
+			this.columnbar = false;
+			(this.rowbar == value || value == 0 || value == 1 )? this.rowbar = false : this.rowbar = value;
+		},
+		addaboverow: function(index)
+		{
+			var row = [];
+			var cols = this.table[0].length;
+			for(var i = 0; i < cols; i++){ row.push("new"); }
+			this.table.splice(index,0,row);
+			this.reindexrows();
+		},
+		addbelowrow: function(index)
+		{
+			var row = [];
+			var cols = this.table[0].length;
+			for(var i = 0; i < cols; i++){ row.push("new"); }
+			this.table.splice(index+1,0,row);
+			this.reindexrows();
+		},
+		deleterow: function(index)
+		{
+			this.table.splice(index,1);
+			this.reindexrows();
+		},
+		addrightcolumn: function(index)
+		{
+			var tableLength = this.table.length;
+			for (var i = 0; i < tableLength; i++)
+			{
+				this.table[i].splice(index+1,0,"new");
+			}
+			this.reindexcolumns();
+		},
+		addleftcolumn: function(index)
+		{
+			var tableLength = this.table.length;
+			for (var i = 0; i < tableLength; i++)
+			{
+				this.table[i].splice(index,0,"new");
+			}
+			this.reindexcolumns();
+		},
+		deletecolumn: function(index)
+		{
+			var tableLength = this.table.length;
+			for (var i = 0; i < tableLength; i++)
+			{
+				this.table[i].splice(index,1);
+			}
+			this.reindexcolumns();
+		},
+		reindexrows: function()
+		{
+			var tableRows = this.table.length;
+			for (var i = 0; i < tableRows; i++)
+			{
+				Vue.set(this.table[i], 0, i);
+			}
+			this.tablekey +=1;
+			this.markdowntable();
+		},
+		reindexcolumns: function()
+		{
+			var tableColumns = this.table[0].length;
+			for (var i = 0; i < tableColumns; i++)
+			{
+				Vue.set(this.table[0], i, i);
+			}
+			this.tablekey +=1;
+			this.markdowntable();
+		},
+		markdowntable: function()
+		{
+			var markdown = '';
+			var separator = '\n|';
+			var rows = this.table.length;
+			var cols = this.table[0].length;
+			
+			for(var i = 0; i < cols; i++)
+			{
+				if(i == 0){ continue; }
+				separator += '---|';
+			}
+			
+			for(var i = 0; i < rows; i++)
+			{
+				var row = this.table[i];
+
+				if(i == 0){ continue; }
+				
+				for(var y = 0; y < cols; y++)
+				{					
+					if(y == 0){ continue; }
+					
+					var value = row[y].trim();
+					
+					if(y == 1)
+					{
+						markdown += '\n| ' + value + ' | ';
+					}
+					else
+					{
+						markdown += value + ' | ';
+					}
+				}
+				if(i == 1) { markdown = markdown + separator; }
+			}
+			this.$emit('updatedMarkdown', markdown);
+		},
+		updatemarkdown: function(event)
+		{
+			/* generate markdown here ??? */
+			this.$emit('updatedMarkdown', event.target.value);
+		},
+	},
+})
 
 
 const videoComponent = Vue.component('video-component', {
 const videoComponent = Vue.component('video-component', {
 	props: ['compmarkdown', 'disabled', 'load'],
 	props: ['compmarkdown', 'disabled', 'load'],
@@ -792,6 +1033,7 @@ let editor = new Vue({
 		'quote-component': quoteComponent,
 		'quote-component': quoteComponent,
 		'ulist-component': ulistComponent,
 		'ulist-component': ulistComponent,
 		'olist-component': olistComponent,
 		'olist-component': olistComponent,
+		'table-component': tableComponent,
 	},
 	},
 	data: {
 	data: {
 		root: document.getElementById("main").dataset.url,
 		root: document.getElementById("main").dataset.url,
@@ -877,6 +1119,12 @@ let editor = new Vue({
 		{
 		{
 			if(block.match(/^\d+\./)){ return "olist-component" }
 			if(block.match(/^\d+\./)){ return "olist-component" }
 			
 			
+			var lines = block.split("\n");
+			if(lines.length > 2 && lines[0].indexOf('|') != -1 && /[\-\|: ]{3,}$/.test(lines[1]))
+			{
+				return "table-component";
+			}
+			
 			var firstChar = block[0];
 			var firstChar = block[0];
 			var secondChar = block[1];
 			var secondChar = block[1];
 			var thirdChar = block[2];
 			var thirdChar = block[2];
@@ -898,10 +1146,10 @@ let editor = new Vue({
 					if(secondChar == "`" && thirdChar == "`") { return "code-component" } else { return "markdown-component" }
 					if(secondChar == "`" && thirdChar == "`") { return "code-component" } else { return "markdown-component" }
 					break;
 					break;
 				case "*":
 				case "*":
+				case "-":
+				case "+":
 					if(secondChar == " "){ return "ulist-component" } else { return "markdown-component" }
 					if(secondChar == " "){ return "ulist-component" } else { return "markdown-component" }
 					break;
 					break;
-				case Number.isInteger(firstChar):
-					if(secondChar == "." ){ return "olist-component" } else { return "markdown-component" }
 				default:
 				default:
 					return 'markdown-component';
 					return 'markdown-component';
 			}
 			}

+ 4 - 1
system/author/js/vue-editor.js

@@ -2,7 +2,10 @@ let editor = new Vue({
     delimiters: ['${', '}'],
     delimiters: ['${', '}'],
 	el: '#editor',
 	el: '#editor',
 	data: {
 	data: {
-		errors: false,
+		errors: {
+			title: false,
+			content: false,
+		},
 		form: {
 		form: {
 			title: document.getElementById("title").value,
 			title: document.getElementById("title").value,
 			content: document.getElementById("content").value,
 			content: document.getElementById("content").value,

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

@@ -114,9 +114,9 @@ const navcomponent = Vue.component('navigation', {
 		{
 		{
 			publishController.errors.message = false;
 			publishController.errors.message = false;
 
 
-			if(this.$root.$data.format.test(this.newItem) || !this.newItem || this.newItem.length > 20)
-			{ 
-				publishController.errors.message = 'Special Characters are not allowed. Length between 1 and 20.';
+			if(this.$root.$data.format.test(this.newItem) || !this.newItem || this.newItem.length > 40)
+			{
+				publishController.errors.message = 'Special Characters are not allowed. Length between 1 and 40.';
 				return;
 				return;
 			}
 			}
 			
 			

+ 55 - 22
system/author/js/vue-publishcontroller.js

@@ -11,8 +11,6 @@ let publishController = new Vue({
 			csrf_value:	document.getElementById("csrf_value").value,
 			csrf_value:	document.getElementById("csrf_value").value,
 		},
 		},
 		errors:{
 		errors:{
-			title: false,
-			content: false,
 			message: false,
 			message: false,
 		},
 		},
 		modalWindow: false,
 		modalWindow: false,
@@ -30,7 +28,8 @@ let publishController = new Vue({
 	methods: {
 	methods: {
 		publishDraft: function(e){
 		publishDraft: function(e){
 			var self = this;
 			var self = this;
-			self.errors = {title: false, content: false, message: false};
+			self.errors.message = false;
+			editor.errors = {title: false, content: false};
 			
 			
 			self.publishResult = "load";
 			self.publishResult = "load";
 			self.publishDisabled = "disabled";
 			self.publishDisabled = "disabled";
@@ -52,7 +51,7 @@ let publishController = new Vue({
 					self.publishResult 		= "fail";
 					self.publishResult 		= "fail";
 					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
 					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
 				}
 				}
-				if(response)
+				else if(response)
 				{					
 				{					
 					var result = JSON.parse(response);
 					var result = JSON.parse(response);
 					
 					
@@ -60,13 +59,10 @@ let publishController = new Vue({
 					{
 					{
 						self.publishDisabled = false;
 						self.publishDisabled = false;
 						self.publishResult = "fail";
 						self.publishResult = "fail";
-						self.errors.message = result.errors.content[0];
 						
 						
-						/*
-						if(result.errors.title){ self.errors.title = result.errors.title[0] };
-						if(result.errors.content){ self.errors.content = result.errors.content[0] };
+						if(result.errors.title){ editor.errors.title = result.errors.title[0] };
+						if(result.errors.content){ editor.errors.content = result.errors.content[0] };
 						if(result.errors.message){ self.errors.message = result.errors.message };
 						if(result.errors.message){ self.errors.message = result.errors.message };
-						*/
 					}
 					}
 					else
 					else
 					{
 					{
@@ -76,12 +72,19 @@ let publishController = new Vue({
 						self.publishLabel = "online";
 						self.publishLabel = "online";
 					}
 					}
 				}
 				}
-			}, method, url, this.form );			
+				else if(httpStatus != 200)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "Something went wrong, please refresh the page and try again."					
+				}				
+			}, method, url, this.form );
 		},
 		},
 		saveDraft: function(e){
 		saveDraft: function(e){
 		
 		
 			var self = this;
 			var self = this;
-			self.errors = {title: false, content: false, message: false};
+			self.errors.message = false;
+			editor.errors = {title: false, content: false};
 			
 			
 			self.draftDisabled = "disabled";
 			self.draftDisabled = "disabled";
 			self.draftResult = "load";
 			self.draftResult = "load";
@@ -100,7 +103,7 @@ let publishController = new Vue({
 					self.publishResult 		= "fail";
 					self.publishResult 		= "fail";
 					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
 					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
 				}
 				}
-				if(response)
+				else if(response)
 				{	
 				{	
 					var result = JSON.parse(response);
 					var result = JSON.parse(response);
 					
 					
@@ -108,18 +111,22 @@ let publishController = new Vue({
 					{
 					{
 						self.draftDisabled = false;
 						self.draftDisabled = false;
 						self.draftResult = 'fail';
 						self.draftResult = 'fail';
-						self.errors.message = result.errors.content[0];
-						/*
-						if(result.errors.title){ self.errors.title = result.errors.title[0] };
-						if(result.errors.content){ self.errors.message = result.errors.content[0] };
-						if(result.errors.message){ self.errors.message = result.errors.message };
-						*/
+
+						if(result.errors.title){ editor.errors.title = result.errors.title[0]; };
+						if(result.errors.content){ editor.errors.content = result.errors.content[0] };
+						if(result.errors.message){ self.errors.message = result.errors.message; };
 					}
 					}
 					else
 					else
 					{
 					{
 						self.draftResult = 'success';
 						self.draftResult = 'success';
 					}
 					}
 				}
 				}
+				else if(httpStatus != 200)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "Something went wrong, please refresh the page and try again."					
+				}
 			}, method, url, this.form );
 			}, method, url, this.form );
 		},
 		},
 		depublishArticle: function(e){
 		depublishArticle: function(e){
@@ -131,7 +138,8 @@ let publishController = new Vue({
 			}
 			}
 			
 			
 			var self = this;
 			var self = this;
-			self.errors = {title: false, content: false, message: false};
+			self.errors.message = false;
+			editor.errors = {title: false, content: false};
 
 
 			self.publishStatus = "disabled";
 			self.publishStatus = "disabled";
 		
 		
@@ -140,7 +148,19 @@ let publishController = new Vue({
 			
 			
 			sendJson(function(response, httpStatus)
 			sendJson(function(response, httpStatus)
 			{
 			{
-				if(response)
+				if(httpStatus == 400)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
+				}
+				else if(httpStatus != 200)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "Something went wrong, please refresh the page and try again."					
+				}
+				else if(response)
 				{
 				{
 					var result = JSON.parse(response);
 					var result = JSON.parse(response);
 					
 					
@@ -160,7 +180,8 @@ let publishController = new Vue({
 		},
 		},
 		deleteArticle: function(e){
 		deleteArticle: function(e){
 			var self = this;
 			var self = this;
-			self.errors = {title: false, content: false, message: false};
+			self.errors.message = false;
+			editor.errors = {title: false, content: false};
 
 
 			self.deleteDisabled = "disabled";
 			self.deleteDisabled = "disabled";
 			self.deleteResult = "load";
 			self.deleteResult = "load";
@@ -170,7 +191,19 @@ let publishController = new Vue({
 
 
 			sendJson(function(response, httpStatus)
 			sendJson(function(response, httpStatus)
 			{
 			{
-				if(response)
+				if(httpStatus == 400)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "You are probably logged out. Please backup your changes, login and then try again."
+				}
+				else if(httpStatus != 200)
+				{
+					self.publishDisabled 	= false;
+					self.publishResult 		= "fail";
+					self.errors.message 	= "Something went wrong, please refresh the page and try again."					
+				}
+				else if(response)
 				{
 				{
 					var result = JSON.parse(response);
 					var result = JSON.parse(response);
 					
 					

+ 14 - 1
system/author/settings/plugins.twig

@@ -43,7 +43,20 @@
 						
 						
 							{% for field in plugin.forms.fields %}
 							{% for field in plugin.forms.fields %}
 								
 								
-								{% include '/partials/fields.twig' with {'itemName' : pluginName, 'object' : 'plugins' } %}
+								{% if field.type == 'fieldset' %}
+											
+									<fieldset class="subfield">
+										<legend>{{ field.legend }}</legend>
+											{% for field in field.fields %}
+												{% include '/partials/fields.twig' with {'itemName' : pluginName, 'object' : 'plugins' } %}
+											{% endfor %}
+										</fieldset>
+											
+								{% else %}
+								
+									{% include '/partials/fields.twig' with {'itemName' : pluginName, 'object' : 'plugins' } %}
+								
+								{% endif %}
 								
 								
 							{% endfor %}
 							{% endfor %}
 							
 							

+ 37 - 25
themes/typemill/css/fontello/config.json

@@ -13,9 +13,33 @@
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
-      "uid": "e9107949dd6c9e8ab2b29ae07156e38c",
-      "css": "linkedin",
-      "code": 61665,
+      "uid": "91426c82d94428a33353e495418435e3",
+      "css": "share",
+      "code": 59393,
+      "src": "entypo"
+    },
+    {
+      "uid": "884cfc3e6e2d456dd2a2ca0dbb9e6337",
+      "css": "left-open-big",
+      "code": 59394,
+      "src": "entypo"
+    },
+    {
+      "uid": "004882ab2d5c418c5b2060e80596279b",
+      "css": "right-open-big",
+      "code": 59395,
+      "src": "entypo"
+    },
+    {
+      "uid": "627abcdb627cb1789e009c08e2678ef9",
+      "css": "twitter",
+      "code": 61593,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "8e04c98c8f5ca0a035776e3001ad2638",
+      "css": "facebook",
+      "code": 61594,
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
@@ -25,9 +49,9 @@
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
-      "uid": "627abcdb627cb1789e009c08e2678ef9",
-      "css": "twitter",
-      "code": 61593,
+      "uid": "e9107949dd6c9e8ab2b29ae07156e38c",
+      "css": "linkedin",
+      "code": 61665,
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
@@ -37,28 +61,16 @@
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
-      "uid": "8e04c98c8f5ca0a035776e3001ad2638",
-      "css": "facebook",
-      "code": 61594,
+      "uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
+      "css": "download",
+      "code": 59396,
       "src": "fontawesome"
       "src": "fontawesome"
     },
     },
     {
     {
-      "uid": "884cfc3e6e2d456dd2a2ca0dbb9e6337",
-      "css": "left-open-big",
-      "code": 59393,
-      "src": "entypo"
-    },
-    {
-      "uid": "004882ab2d5c418c5b2060e80596279b",
-      "css": "right-open-big",
-      "code": 59394,
-      "src": "entypo"
-    },
-    {
-      "uid": "91426c82d94428a33353e495418435e3",
-      "css": "share-1",
-      "code": 59395,
-      "src": "entypo"
+      "uid": "0f6a2573a7b6df911ed199bb63717e27",
+      "css": "github-circled",
+      "code": 61595,
+      "src": "fontawesome"
     }
     }
   ]
   ]
 }
 }

+ 5 - 3
themes/typemill/css/fontello/css/fontello-codes.css

@@ -1,10 +1,12 @@
 
 
 .icon-mail:before { content: '\e800'; } /* '' */
 .icon-mail:before { content: '\e800'; } /* '' */
-.icon-left-open-big:before { content: '\e801'; } /* '' */
-.icon-right-open-big:before { content: '\e802'; } /* '' */
-.icon-share-1:before { content: '\e803'; } /* '' */
+.icon-share:before { content: '\e801'; } /* '' */
+.icon-left-open-big:before { content: '\e802'; } /* '' */
+.icon-right-open-big:before { content: '\e803'; } /* '' */
+.icon-download:before { content: '\e804'; } /* '' */
 .icon-twitter:before { content: '\f099'; } /* '' */
 .icon-twitter:before { content: '\f099'; } /* '' */
 .icon-facebook:before { content: '\f09a'; } /* '' */
 .icon-facebook:before { content: '\f09a'; } /* '' */
+.icon-github-circled:before { content: '\f09b'; } /* '' */
 .icon-linkedin:before { content: '\f0e1'; } /* '' */
 .icon-linkedin:before { content: '\f0e1'; } /* '' */
 .icon-xing:before { content: '\f168'; } /* '' */
 .icon-xing:before { content: '\f168'; } /* '' */
 .icon-whatsapp:before { content: '\f232'; } /* '' */
 .icon-whatsapp:before { content: '\f232'; } /* '' */

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 3
themes/typemill/css/fontello/css/fontello-embedded.css


+ 5 - 3
themes/typemill/css/fontello/css/fontello-ie7-codes.css

@@ -1,10 +1,12 @@
 
 
 .icon-mail { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
 .icon-mail { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
-.icon-left-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
-.icon-right-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
-.icon-share-1 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
+.icon-share { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
+.icon-left-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
+.icon-right-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
+.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
 .icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }
 .icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }
 .icon-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09a;&nbsp;'); }
 .icon-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09a;&nbsp;'); }
+.icon-github-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09b;&nbsp;'); }
 .icon-linkedin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e1;&nbsp;'); }
 .icon-linkedin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e1;&nbsp;'); }
 .icon-xing { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf168;&nbsp;'); }
 .icon-xing { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf168;&nbsp;'); }
 .icon-whatsapp { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf232;&nbsp;'); }
 .icon-whatsapp { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf232;&nbsp;'); }

+ 5 - 3
themes/typemill/css/fontello/css/fontello-ie7.css

@@ -11,11 +11,13 @@
 }
 }
  
  
 .icon-mail { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
 .icon-mail { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
-.icon-left-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
-.icon-right-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
-.icon-share-1 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
+.icon-share { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
+.icon-left-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
+.icon-right-open-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
+.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
 .icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }
 .icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }
 .icon-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09a;&nbsp;'); }
 .icon-facebook { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09a;&nbsp;'); }
+.icon-github-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf09b;&nbsp;'); }
 .icon-linkedin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e1;&nbsp;'); }
 .icon-linkedin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e1;&nbsp;'); }
 .icon-xing { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf168;&nbsp;'); }
 .icon-xing { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf168;&nbsp;'); }
 .icon-whatsapp { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf232;&nbsp;'); }
 .icon-whatsapp { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf232;&nbsp;'); }

+ 12 - 10
themes/typemill/css/fontello/css/fontello.css

@@ -1,11 +1,11 @@
 @font-face {
 @font-face {
   font-family: 'fontello';
   font-family: 'fontello';
-  src: url('../font/fontello.eot?45966989');
-  src: url('../font/fontello.eot?45966989#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?45966989') format('woff2'),
-       url('../font/fontello.woff?45966989') format('woff'),
-       url('../font/fontello.ttf?45966989') format('truetype'),
-       url('../font/fontello.svg?45966989#fontello') format('svg');
+  src: url('../font/fontello.eot?8743082');
+  src: url('../font/fontello.eot?8743082#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?8743082') format('woff2'),
+       url('../font/fontello.woff?8743082') format('woff'),
+       url('../font/fontello.ttf?8743082') format('truetype'),
+       url('../font/fontello.svg?8743082#fontello') format('svg');
   font-weight: normal;
   font-weight: normal;
   font-style: normal;
   font-style: normal;
 }
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
   @font-face {
     font-family: 'fontello';
     font-family: 'fontello';
-    src: url('../font/fontello.svg?45966989#fontello') format('svg');
+    src: url('../font/fontello.svg?8743082#fontello') format('svg');
   }
   }
 }
 }
 */
 */
@@ -56,11 +56,13 @@
 }
 }
  
  
 .icon-mail:before { content: '\e800'; } /* '' */
 .icon-mail:before { content: '\e800'; } /* '' */
-.icon-left-open-big:before { content: '\e801'; } /* '' */
-.icon-right-open-big:before { content: '\e802'; } /* '' */
-.icon-share-1:before { content: '\e803'; } /* '' */
+.icon-share:before { content: '\e801'; } /* '' */
+.icon-left-open-big:before { content: '\e802'; } /* '' */
+.icon-right-open-big:before { content: '\e803'; } /* '' */
+.icon-download:before { content: '\e804'; } /* '' */
 .icon-twitter:before { content: '\f099'; } /* '' */
 .icon-twitter:before { content: '\f099'; } /* '' */
 .icon-facebook:before { content: '\f09a'; } /* '' */
 .icon-facebook:before { content: '\f09a'; } /* '' */
+.icon-github-circled:before { content: '\f09b'; } /* '' */
 .icon-linkedin:before { content: '\f0e1'; } /* '' */
 .icon-linkedin:before { content: '\f0e1'; } /* '' */
 .icon-xing:before { content: '\f168'; } /* '' */
 .icon-xing:before { content: '\f168'; } /* '' */
 .icon-whatsapp:before { content: '\f232'; } /* '' */
 .icon-whatsapp:before { content: '\f232'; } /* '' */

+ 12 - 10
themes/typemill/css/fontello/demo.html

@@ -229,11 +229,11 @@ body {
 }
 }
 @font-face {
 @font-face {
       font-family: 'fontello';
       font-family: 'fontello';
-      src: url('./font/fontello.eot?98470540');
-      src: url('./font/fontello.eot?98470540#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?98470540') format('woff'),
-           url('./font/fontello.ttf?98470540') format('truetype'),
-           url('./font/fontello.svg?98470540#fontello') format('svg');
+      src: url('./font/fontello.eot?27459207');
+      src: url('./font/fontello.eot?27459207#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?27459207') format('woff'),
+           url('./font/fontello.ttf?27459207') format('truetype'),
+           url('./font/fontello.svg?27459207#fontello') format('svg');
       font-weight: normal;
       font-weight: normal;
       font-style: normal;
       font-style: normal;
     }
     }
@@ -299,17 +299,19 @@ body {
     <div class="container" id="icons">
     <div class="container" id="icons">
       <div class="row">
       <div class="row">
         <div class="the-icons span3" title="Code: 0xe800"><i class="demo-icon icon-mail">&#xe800;</i> <span class="i-name">icon-mail</span><span class="i-code">0xe800</span></div>
         <div class="the-icons span3" title="Code: 0xe800"><i class="demo-icon icon-mail">&#xe800;</i> <span class="i-name">icon-mail</span><span class="i-code">0xe800</span></div>
-        <div class="the-icons span3" title="Code: 0xe801"><i class="demo-icon icon-left-open-big">&#xe801;</i> <span class="i-name">icon-left-open-big</span><span class="i-code">0xe801</span></div>
-        <div class="the-icons span3" title="Code: 0xe802"><i class="demo-icon icon-right-open-big">&#xe802;</i> <span class="i-name">icon-right-open-big</span><span class="i-code">0xe802</span></div>
-        <div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-share-1">&#xe803;</i> <span class="i-name">icon-share-1</span><span class="i-code">0xe803</span></div>
+        <div class="the-icons span3" title="Code: 0xe801"><i class="demo-icon icon-share">&#xe801;</i> <span class="i-name">icon-share</span><span class="i-code">0xe801</span></div>
+        <div class="the-icons span3" title="Code: 0xe802"><i class="demo-icon icon-left-open-big">&#xe802;</i> <span class="i-name">icon-left-open-big</span><span class="i-code">0xe802</span></div>
+        <div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-right-open-big">&#xe803;</i> <span class="i-name">icon-right-open-big</span><span class="i-code">0xe803</span></div>
       </div>
       </div>
       <div class="row">
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xe804"><i class="demo-icon icon-download">&#xe804;</i> <span class="i-name">icon-download</span><span class="i-code">0xe804</span></div>
         <div class="the-icons span3" title="Code: 0xf099"><i class="demo-icon icon-twitter">&#xf099;</i> <span class="i-name">icon-twitter</span><span class="i-code">0xf099</span></div>
         <div class="the-icons span3" title="Code: 0xf099"><i class="demo-icon icon-twitter">&#xf099;</i> <span class="i-name">icon-twitter</span><span class="i-code">0xf099</span></div>
         <div class="the-icons span3" title="Code: 0xf09a"><i class="demo-icon icon-facebook">&#xf09a;</i> <span class="i-name">icon-facebook</span><span class="i-code">0xf09a</span></div>
         <div class="the-icons span3" title="Code: 0xf09a"><i class="demo-icon icon-facebook">&#xf09a;</i> <span class="i-name">icon-facebook</span><span class="i-code">0xf09a</span></div>
-        <div class="the-icons span3" title="Code: 0xf0e1"><i class="demo-icon icon-linkedin">&#xf0e1;</i> <span class="i-name">icon-linkedin</span><span class="i-code">0xf0e1</span></div>
-        <div class="the-icons span3" title="Code: 0xf168"><i class="demo-icon icon-xing">&#xf168;</i> <span class="i-name">icon-xing</span><span class="i-code">0xf168</span></div>
+        <div class="the-icons span3" title="Code: 0xf09b"><i class="demo-icon icon-github-circled">&#xf09b;</i> <span class="i-name">icon-github-circled</span><span class="i-code">0xf09b</span></div>
       </div>
       </div>
       <div class="row">
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf0e1"><i class="demo-icon icon-linkedin">&#xf0e1;</i> <span class="i-name">icon-linkedin</span><span class="i-code">0xf0e1</span></div>
+        <div class="the-icons span3" title="Code: 0xf168"><i class="demo-icon icon-xing">&#xf168;</i> <span class="i-name">icon-xing</span><span class="i-code">0xf168</span></div>
         <div class="the-icons span3" title="Code: 0xf232"><i class="demo-icon icon-whatsapp">&#xf232;</i> <span class="i-name">icon-whatsapp</span><span class="i-code">0xf232</span></div>
         <div class="the-icons span3" title="Code: 0xf232"><i class="demo-icon icon-whatsapp">&#xf232;</i> <span class="i-name">icon-whatsapp</span><span class="i-code">0xf232</span></div>
       </div>
       </div>
     </div>
     </div>

BIN
themes/typemill/css/fontello/font/fontello.eot


+ 8 - 4
themes/typemill/css/fontello/font/fontello.svg

@@ -1,23 +1,27 @@
 <?xml version="1.0" standalone="no"?>
 <?xml version="1.0" standalone="no"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <svg xmlns="http://www.w3.org/2000/svg">
 <svg xmlns="http://www.w3.org/2000/svg">
-<metadata>Copyright (C) 2018 by original authors @ fontello.com</metadata>
+<metadata>Copyright (C) 2019 by original authors @ fontello.com</metadata>
 <defs>
 <defs>
 <font id="fontello" horiz-adv-x="1000" >
 <font id="fontello" horiz-adv-x="1000" >
 <font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
 <font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
 <missing-glyph horiz-adv-x="1000" />
 <missing-glyph horiz-adv-x="1000" />
 <glyph glyph-name="mail" unicode="&#xe800;" d="M929 11v428q-18-20-39-36-149-115-238-189-28-24-46-37t-48-28-57-13h-2q-26 0-57 13t-48 28-46 37q-88 74-238 189-21 16-39 36v-428q0-7 6-13t12-5h822q7 0 12 5t6 13z m0 586v14t-1 7-1 7-3 5-5 4-8 2h-822q-7 0-12-6t-6-12q0-94 83-159 107-84 223-176 4-3 20-17t25-21 25-17 28-16 24-5h2q11 0 24 5t28 16 25 17 25 21 20 17q116 92 224 176 30 24 56 65t26 73z m71 21v-607q0-37-26-63t-63-27h-822q-36 0-63 27t-26 63v607q0 37 26 63t63 26h822q37 0 63-26t26-63z" horiz-adv-x="1000" />
 <glyph glyph-name="mail" unicode="&#xe800;" d="M929 11v428q-18-20-39-36-149-115-238-189-28-24-46-37t-48-28-57-13h-2q-26 0-57 13t-48 28-46 37q-88 74-238 189-21 16-39 36v-428q0-7 6-13t12-5h822q7 0 12 5t6 13z m0 586v14t-1 7-1 7-3 5-5 4-8 2h-822q-7 0-12-6t-6-12q0-94 83-159 107-84 223-176 4-3 20-17t25-21 25-17 28-16 24-5h2q11 0 24 5t28 16 25 17 25 21 20 17q116 92 224 176 30 24 56 65t26 73z m71 21v-607q0-37-26-63t-63-27h-822q-36 0-63 27t-26 63v607q0 37 26 63t63 26h822q37 0 63-26t26-63z" horiz-adv-x="1000" />
 
 
-<glyph glyph-name="left-open-big" unicode="&#xe801;" d="M452-20q26-26 0-48-26-26-48 0l-392 394q-24 24 0 50l392 394q22 26 48 0 26-22 0-48l-358-372z" horiz-adv-x="465" />
+<glyph glyph-name="share" unicode="&#xe801;" d="M650 200q62 0 106-43t44-107q0-62-44-106t-106-44-106 44-44 106q0 6 1 14t1 12l-260 156q-42-32-92-32-62 0-106 44t-44 106 44 106 106 44q54 0 92-30l260 156q0 4-1 12t-1 12q0 62 44 106t106 44 106-43 44-107q0-62-44-106t-106-44q-52 0-90 32l-262-156q2-8 2-26 0-16-2-24l262-156q36 30 90 30z" horiz-adv-x="800" />
 
 
-<glyph glyph-name="right-open-big" unicode="&#xe802;" d="M13-20l358 370-358 372q-26 26 0 48 26 26 48 0l392-394q24-26 0-50l-392-394q-22-26-48 0-26 22 0 48z" horiz-adv-x="465" />
+<glyph glyph-name="left-open-big" unicode="&#xe802;" d="M452-20q26-26 0-48-26-26-48 0l-392 394q-24 24 0 50l392 394q22 26 48 0 26-22 0-48l-358-372z" horiz-adv-x="465" />
 
 
-<glyph glyph-name="share-1" unicode="&#xe803;" d="M650 200q62 0 106-43t44-107q0-62-44-106t-106-44-106 44-44 106q0 6 1 14t1 12l-260 156q-42-32-92-32-62 0-106 44t-44 106 44 106 106 44q54 0 92-30l260 156q0 4-1 12t-1 12q0 62 44 106t106 44 106-43 44-107q0-62-44-106t-106-44q-52 0-90 32l-262-156q2-8 2-26 0-16-2-24l262-156q36 30 90 30z" horiz-adv-x="800" />
+<glyph glyph-name="right-open-big" unicode="&#xe803;" d="M13-20l358 370-358 372q-26 26 0 48 26 26 48 0l392-394q24-26 0-50l-392-394q-22-26-48 0-26 22 0 48z" horiz-adv-x="465" />
+
+<glyph glyph-name="download" unicode="&#xe804;" d="M714 100q0 15-10 25t-25 11-25-11-11-25 11-25 25-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-39l-250-250q-10-11-25-11t-25 11l-250 250q-17 16-8 39 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" />
 
 
 <glyph glyph-name="twitter" unicode="&#xf099;" d="M904 622q-37-54-90-93 0-8 0-23 0-73-21-145t-64-139-103-117-144-82-181-30q-151 0-276 81 19-2 43-2 126 0 224 77-59 1-105 36t-64 89q19-3 34-3 24 0 48 6-63 13-104 62t-41 115v2q38-21 82-23-37 25-59 64t-22 86q0 49 25 91 68-83 164-133t208-55q-5 21-5 41 0 75 53 127t127 53q79 0 132-57 61 12 115 44-21-64-80-100 52 6 104 28z" horiz-adv-x="928.6" />
 <glyph glyph-name="twitter" unicode="&#xf099;" d="M904 622q-37-54-90-93 0-8 0-23 0-73-21-145t-64-139-103-117-144-82-181-30q-151 0-276 81 19-2 43-2 126 0 224 77-59 1-105 36t-64 89q19-3 34-3 24 0 48 6-63 13-104 62t-41 115v2q38-21 82-23-37 25-59 64t-22 86q0 49 25 91 68-83 164-133t208-55q-5 21-5 41 0 75 53 127t127 53q79 0 132-57 61 12 115 44-21-64-80-100 52 6 104 28z" horiz-adv-x="928.6" />
 
 
 <glyph glyph-name="facebook" unicode="&#xf09a;" d="M535 843v-147h-87q-48 0-65-20t-17-60v-106h164l-22-165h-142v-424h-171v424h-142v165h142v122q0 104 58 161t155 57q82 0 127-7z" horiz-adv-x="571.4" />
 <glyph glyph-name="facebook" unicode="&#xf09a;" d="M535 843v-147h-87q-48 0-65-20t-17-60v-106h164l-22-165h-142v-424h-171v424h-142v165h142v122q0 104 58 161t155 57q82 0 127-7z" horiz-adv-x="571.4" />
 
 
+<glyph glyph-name="github-circled" unicode="&#xf09b;" d="M429 779q116 0 215-58t156-156 57-215q0-140-82-252t-211-155q-15-3-22 4t-7 17q0 1 0 43t0 75q0 54-29 79 32 3 57 10t53 22 45 37 30 58 11 84q0 67-44 115 21 51-4 114-16 5-46-6t-51-25l-21-13q-52 15-107 15t-108-15q-8 6-23 15t-47 22-47 7q-25-63-5-114-44-48-44-115 0-47 12-83t29-59 45-37 52-22 57-10q-21-20-27-58-12-5-25-8t-32-3-36 12-31 35q-11 18-27 29t-28 14l-11 1q-12 0-16-2t-3-7 5-8 7-6l4-3q12-6 24-21t18-29l6-13q7-21 24-34t37-17 39-3 31 1l13 3q0-22 0-50t1-30q0-10-8-17t-22-4q-129 43-211 155t-82 252q0 117 58 215t155 156 216 58z m-267-616q2 4-3 7-6 1-8-1-1-4 4-7 5-3 7 1z m18-19q4 3-1 9-6 5-9 2-4-3 1-9 5-6 9-2z m16-25q6 4 0 11-4 7-9 3-5-3 0-10t9-4z m24-23q4 4-2 10-7 7-11 2-5-5 2-11 6-6 11-1z m32-14q1 6-8 9-8 2-10-4t7-9q8-3 11 4z m35-3q0 7-10 6-9 0-9-6 0-7 10-6 9 0 9 6z m32 5q-1 7-10 5-9-1-8-8t10-4 8 7z" horiz-adv-x="857.1" />
+
 <glyph glyph-name="linkedin" unicode="&#xf0e1;" d="M195 501v-553h-184v553h184z m12 171q0-41-29-68t-75-27h-1q-46 0-74 27t-28 68q0 41 29 68t75 27 74-27 29-68z m650-407v-317h-183v296q0 59-23 92t-71 33q-35 0-58-19t-36-48q-6-17-6-45v-309h-184q1 223 1 361t0 165l-1 27h184v-80h-1q11 18 23 31t31 29 49 24 64 9q95 0 153-63t58-186z" horiz-adv-x="857.1" />
 <glyph glyph-name="linkedin" unicode="&#xf0e1;" d="M195 501v-553h-184v553h184z m12 171q0-41-29-68t-75-27h-1q-46 0-74 27t-28 68q0 41 29 68t75 27 74-27 29-68z m650-407v-317h-183v296q0 59-23 92t-71 33q-35 0-58-19t-36-48q-6-17-6-45v-309h-184q1 223 1 361t0 165l-1 27h184v-80h-1q11 18 23 31t31 29 49 24 64 9q95 0 153-63t58-186z" horiz-adv-x="857.1" />
 
 
 <glyph glyph-name="xing" unicode="&#xf168;" d="M333 478q-5-10-143-255-15-25-36-25h-134q-12 0-17 9t0 20l141 250q1 0 0 1l-90 156q-7 12 0 20 5 9 17 9h134q22 0 37-26z m450 358q6-9 0-21l-295-521v0l188-344q6-11 0-20-5-9-17-9h-134q-23 0-37 25l-189 348q10 18 296 525 14 25 36 25h135q12 0 17-8z" horiz-adv-x="785.7" />
 <glyph glyph-name="xing" unicode="&#xf168;" d="M333 478q-5-10-143-255-15-25-36-25h-134q-12 0-17 9t0 20l141 250q1 0 0 1l-90 156q-7 12 0 20 5 9 17 9h134q22 0 37-26z m450 358q6-9 0-21l-295-521v0l188-344q6-11 0-20-5-9-17-9h-134q-23 0-37 25l-189 348q10 18 296 525 14 25 36 25h135q12 0 17-8z" horiz-adv-x="785.7" />

BIN
themes/typemill/css/fontello/font/fontello.ttf


BIN
themes/typemill/css/fontello/font/fontello.woff


BIN
themes/typemill/css/fontello/font/fontello.woff2


+ 3 - 0
themes/typemill/css/style.css

@@ -377,6 +377,9 @@ article button.play-video::after {
 	border-color: transparent transparent transparent rgba(255, 255, 255, 0.75);
 	border-color: transparent transparent transparent rgba(255, 255, 255, 0.75);
 	content: ' ';
 	content: ' ';
 }
 }
+article .gitlink{
+	float: right;
+}
 
 
 /************************
 /************************
 *  	PAGING / BREADCRUMB *
 *  	PAGING / BREADCRUMB *

+ 8 - 3
themes/typemill/page.twig

@@ -6,7 +6,7 @@
 
 
 <h1>{{ title }}</h1>
 <h1>{{ title }}</h1>
 
 
-{% if (settings.themes.typemill.socialPosition.top or settings.themes.typemill.modifiedPosition.top or settings.themes.typemill.authorPosition.top) %}	
+{% if (settings.themes.typemill.socialPosition.top or settings.themes.typemill.modifiedPosition.top or settings.themes.typemill.authorPosition.top or settings.themes.typemill.gitPosition.top) %}	
 	<div class="meta-info">
 	<div class="meta-info">
 		{% if settings.themes.typemill.authorPosition.top %}
 		{% if settings.themes.typemill.authorPosition.top %}
 			<small>{{ settings.themes.typemill.authorIntro }}: {{ settings.author }}</small>
 			<small>{{ settings.themes.typemill.authorIntro }}: {{ settings.author }}</small>
@@ -22,13 +22,16 @@
 				</div>
 				</div>
 			</div>
 			</div>
 		{% endif %}
 		{% endif %}
+		{% if settings.themes.typemill.gitPosition.top %} 
+			<div class="gitlink"><a title="edit on git" href="{{ settings.themes.typemill.gitlink }}/{{ item.urlRel }}">edit <i class="icon-github-circled"></i></a></div>
+		{% endif %}
 	</div>
 	</div>
 {% endif %}
 {% endif %}
 
 
 {{ content }}
 {{ content }}
 
 
 
 
-{% if (settings.themes.typemill.socialPosition.bottom or settings.themes.typemill.modifiedPosition.bottom or settings.themes.typemill.authorPosition.bottom) %}	
+{% if (settings.themes.typemill.socialPosition.bottom or settings.themes.typemill.modifiedPosition.bottom or settings.themes.typemill.authorPosition.bottom or settings.themes.typemill.gitPosition.bottom) %}	
 	<div class="meta-info">
 	<div class="meta-info">
 		{% if settings.themes.typemill.authorPosition.bottom %}
 		{% if settings.themes.typemill.authorPosition.bottom %}
 			<small>{{ settings.themes.typemill.authorIntro }}: {{ settings.author }}</small>
 			<small>{{ settings.themes.typemill.authorIntro }}: {{ settings.author }}</small>
@@ -44,11 +47,13 @@
 				</div>
 				</div>
 			</div>
 			</div>
 		{% endif %}
 		{% endif %}
+		{% if settings.themes.typemill.gitPosition.bottom %} 
+			<div class="gitlink"><a title="edit on git" href="{{ settings.themes.typemill.gitlink }}/{{ item.urlRel }}">edit <i class="icon-github-circled"></i></a></div>
+		{% endif %}		
 	</div>
 	</div>
 {% endif %}
 {% endif %}
 
 
 
 
-
 {% if item.prevItem or item.nextItem %}
 {% if item.prevItem or item.nextItem %}
 
 
 	<div class="paging">
 	<div class="paging">

+ 5 - 5
themes/typemill/partials/navigation.twig

@@ -1,4 +1,4 @@
-{% macro loop_over(navigation) %}
+{% macro loop_over(navigation,chapnum) %}
 
 
     {% import _self as macros %}
     {% import _self as macros %}
 
 
@@ -14,12 +14,12 @@
 			<li class="{{ element.elementType }} level-{{ depth }}">
 			<li class="{{ element.elementType }} level-{{ depth }}">
 		{% endif %}
 		{% endif %}
             {% if (element.elementType == 'folder') %}
             {% if (element.elementType == 'folder') %}
-				<a href="{{ element.urlAbs }}">{{ element.name }}</a>		
+				<a href="{{ element.urlAbs }}">{% if chapnum %}{{ element.chapter }}. {% endif %}{{ element.name }}</a>		
                 <ul>
                 <ul>
-                    {{ macros.loop_over(element.folderContent) }}
+                    {{ macros.loop_over(element.folderContent,chapnum) }}
                 </ul>
                 </ul>
             {% else %}
             {% else %}
-				<a href="{{ element.urlAbs }}">{{ element.name }}</a>
+				<a href="{{ element.urlAbs }}">{% if chapnum %}{{ element.chapter }} {% endif %}{{ element.name }}</a>
             {% endif %}
             {% endif %}
         </li>
         </li>
     {% endfor %}
     {% endfor %}
@@ -28,5 +28,5 @@
 {% import _self as macros %}
 {% import _self as macros %}
 
 
 <ul>
 <ul>
-    {{ macros.loop_over(navigation) }}
+    {{ macros.loop_over(navigation,settings.themes.typemill.chapnum) }}
 </ul>
 </ul>

+ 24 - 2
themes/typemill/typemill.yaml

@@ -1,5 +1,5 @@
 name: Typemill Theme
 name: Typemill Theme
-version: 1.1.3
+version: 1.1.4
 description: The standard theme for Typemill. Responsive, minimal and without any dependencies. It uses the system fonts Calibri and Helvetica. No JavaScript is used. 
 description: The standard theme for Typemill. Responsive, minimal and without any dependencies. It uses the system fonts Calibri and Helvetica. No JavaScript is used. 
 author: Sebastian Schürmanns
 author: Sebastian Schürmanns
 homepage: https://typemill.net
 homepage: https://typemill.net
@@ -30,6 +30,11 @@ forms:
       placeholder: Add Label for Start-Button
       placeholder: Add Label for Start-Button
       required: true
       required: true
 
 
+    chapnum:
+      type: checkbox
+      label: Chapter Numbers
+      checkboxlabel: Count chapters in navigation?
+
     fieldset0:
     fieldset0:
       type: fieldset
       type: fieldset
       legend: Author
       legend: Author
@@ -90,4 +95,21 @@ forms:
             xing: Xing
             xing: Xing
             linkedin: Linkedin
             linkedin: Linkedin
             whatsapp: WhatsApp
             whatsapp: WhatsApp
-            mail: Mail
+            mail: Mail
+
+    fieldset3:
+      type: fieldset
+      legend: GitHub
+      fields:
+        gitPosition:
+          type: checkboxlist
+          label: Position of Git Edit Link
+          options:
+            top: Top
+            bottom: Bottom
+
+        gitlink:
+          type: text
+          label: Link to git repository
+          placeholder: https://github.com/typemill/documentation
+          help: Please add the base url to the text repository e.g. on github.

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels