| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var actions = require('lib/actions') | 
					
						
							|  |  |  | var features = require('lib/features') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var core = require('features/core') | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | var browse = require('lib/widget/browse') | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | var widgets = require('features/ui-widgets') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2019-10-13 04:51:29 +03:00
										 |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | // XXX should these be sortable and how???
 | 
					
						
							|  |  |  | // 		...relative placement (i.e. "before <GID>")???
 | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | // 		.....might be a good idea to add option to "pair" images as a 
 | 
					
						
							|  |  |  | // 		generic sort thing -- is this grouping???
 | 
					
						
							| 
									
										
										
										
											2019-10-13 04:51:29 +03:00
										 |  |  | // XXX should the export mechanism be extensible???
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:37:45 +03:00
										 |  |  | // XXX add undo...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 05:35:29 +03:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | // 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | var VirtualBlocksActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2019-10-23 16:12:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// XXX do we need to pre-cache this???
 | 
					
						
							|  |  |  | 	get virtual(){ | 
					
						
							|  |  |  | 		var that = this | 
					
						
							|  |  |  | 		return this.data.order | 
					
						
							|  |  |  | 			.filter(function(gid){  | 
					
						
							| 
									
										
										
										
											2020-05-02 21:03:12 +03:00
										 |  |  | 				var img = that.images[gid] || {} | 
					
						
							| 
									
										
										
										
											2019-10-23 16:12:53 +03:00
										 |  |  | 				return img.type == 'virtual' }) }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	// construction of new "virtual images"...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:37:45 +03:00
										 |  |  | 	// XXX add undo...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:49:02 +03:00
										 |  |  | 	// XXX do better arg processing -- handle data correctly...
 | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 	makeVirtualBlock: ['Virtual block/Add blank $after', | 
					
						
							|  |  |  | 		core.doc`Add virtual block...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:49:02 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 				Add virtual block after current image... | 
					
						
							|  |  |  | 				.makeVirtualBlock() | 
					
						
							|  |  |  | 				.makeVirtualBlock('current') | 
					
						
							|  |  |  | 				.makeVirtualBlock('current', 'after') | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 					-> this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 				Add virtual block before current image... | 
					
						
							|  |  |  | 				.makeVirtualBlock('current') | 
					
						
							|  |  |  | 				.makeVirtualBlock('current', 'after') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Add virtual block at offset relative to reference image, | 
					
						
							|  |  |  | 				optionally containing data... | 
					
						
							|  |  |  | 				.makeVirtualBlock(reference, offset) | 
					
						
							|  |  |  | 				.makeVirtualBlock(reference, offset, data) | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 					-> this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 			NOTE: reference if not given defaults to 'current' | 
					
						
							|  |  |  | 			NOTE: data if not given will default to: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					type: 'virtual', | 
					
						
							|  |  |  | 					path: null, | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:49:02 +03:00
										 |  |  | 			Virtual Block Format (Image): | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					// block type...
 | 
					
						
							|  |  |  | 					type: 'virtual', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// Block name (optional)...
 | 
					
						
							|  |  |  | 					//
 | 
					
						
							|  |  |  | 					// NOTE: this is a standard Image attribute used to generate 
 | 
					
						
							|  |  |  | 					//		exported image filename...
 | 
					
						
							|  |  |  | 					// NOTE: if it is required to change exported file extension 
 | 
					
						
							|  |  |  | 					//		from '.txt' add the extension to the name...
 | 
					
						
							|  |  |  | 					//			Example:
 | 
					
						
							|  |  |  | 					//				name: 'virtual-image.tex'
 | 
					
						
							|  |  |  | 					name: <String>, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// Block text (optional)...
 | 
					
						
							|  |  |  | 					text: <String>, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// export constructor action...
 | 
					
						
							|  |  |  | 					//
 | 
					
						
							|  |  |  | 					// XXX not implemented yet...
 | 
					
						
							|  |  |  | 					//export: <action>,
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// optional image attributes...
 | 
					
						
							|  |  |  | 					// for more info see: imagegrid/images.js
 | 
					
						
							|  |  |  | 					... | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			`,
 | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: function(){ return !this.collection && 'disabled' }, }, | 
					
						
							| 
									
										
										
										
											2019-10-13 22:05:50 +03:00
										 |  |  | 		function(ref, offset, img){ | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 			ref = ref || 'current' | 
					
						
							|  |  |  | 			offset = offset || 'after'	 | 
					
						
							|  |  |  | 			offset = offset == 'after' ?  | 
					
						
							|  |  |  | 					1  | 
					
						
							|  |  |  | 				: offset == 'before' ?  | 
					
						
							|  |  |  | 					0 | 
					
						
							|  |  |  | 				: typeof(offset) == typeof(123) ? | 
					
						
							|  |  |  | 					offset | 
					
						
							|  |  |  | 				: 0 | 
					
						
							|  |  |  | 			// XXX revise...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 22:05:50 +03:00
										 |  |  | 			img = arguments[arguments.length-1] instanceof Object ? | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 				arguments[arguments.length-1] | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 				: undefined | 
					
						
							|  |  |  | 			img = img === null ?  | 
					
						
							|  |  |  | 				img  | 
					
						
							|  |  |  | 				: Object.assign({ | 
					
						
							|  |  |  | 						type: 'virtual',  | 
					
						
							|  |  |  | 						path: null, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					img || {}) | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var data = this.data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ref = data.getImage(ref) | 
					
						
							|  |  |  | 			var r = data.getRibbon(ref) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var gid = data.newGID() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// place image into data...
 | 
					
						
							|  |  |  | 			var order = data.order | 
					
						
							|  |  |  | 			order.splice(order.indexOf(ref)+offset,0, gid) | 
					
						
							|  |  |  | 			var ribbon = data.ribbons[r] | 
					
						
							|  |  |  | 			ribbon.splice(ribbon.indexOf(ref)+offset,0, gid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// update data...
 | 
					
						
							|  |  |  | 			data.updateImagePositions() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:49:02 +03:00
										 |  |  | 			// update data...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 22:05:50 +03:00
										 |  |  | 			img | 
					
						
							|  |  |  | 				&& (this.images[gid] = img) | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 			this.markChanged | 
					
						
							| 
									
										
										
										
											2019-10-13 04:33:36 +03:00
										 |  |  | 				&& this | 
					
						
							|  |  |  | 					.markChanged('data') | 
					
						
							|  |  |  | 					.markChanged('images', [gid]) | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// focus new image...
 | 
					
						
							|  |  |  | 			// NOTE: this should update the view too...
 | 
					
						
							|  |  |  | 			this.focusImage(gid) | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 	makeVirtualBlockBefore: ['Virtual block/Add blank $before', | 
					
						
							| 
									
										
										
										
											2019-10-26 01:12:05 +03:00
										 |  |  | 		core.doc`Add block before...
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 			This is the same as .makeVirtualBlock(.., 'before', ..)`,
 | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: 'makeVirtualBlock', }, | 
					
						
							| 
									
										
										
										
											2019-10-25 16:23:20 +03:00
										 |  |  | 		'makeVirtualBlock: $0 "before" ...'], | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 01:25:48 +03:00
										 |  |  | 	cloneVirtualBlock: ['Virtual block/$Clone block', | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: function(){  | 
					
						
							| 
									
										
										
										
											2019-10-23 16:05:39 +03:00
										 |  |  | 			return (this.image || {}).type != 'virtual' && 'disabled' }, }, | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 		function(ref, offset, img){ | 
					
						
							|  |  |  | 			var img = Object.assign({},  | 
					
						
							|  |  |  | 				this.images[this.data.getImage(ref)] || {},  | 
					
						
							|  |  |  | 				img || {}) | 
					
						
							|  |  |  | 			delete img.gid | 
					
						
							|  |  |  | 			this.makeVirtualBlock(ref, offset, img) }], | 
					
						
							| 
									
										
										
										
											2019-10-23 16:05:39 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// crop...
 | 
					
						
							| 
									
										
										
										
											2019-10-24 04:40:45 +03:00
										 |  |  | 	// XXX would be nice to avoid these and just register a list and context...
 | 
					
						
							| 
									
										
										
										
											2019-10-25 01:25:48 +03:00
										 |  |  | 	cropVirtualBlocks: ['Virtual block|Crop/$Crop $virtual $blocks', | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: 'makeVirtualBlock' }, | 
					
						
							| 
									
										
										
										
											2019-10-24 04:40:45 +03:00
										 |  |  | 		'crop: "virtual" ...'], | 
					
						
							| 
									
										
										
										
											2019-10-23 16:05:39 +03:00
										 |  |  | 	cropVirtualBlocksOut: ['Virtual block|Crop/Crop virtual blocks out', | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: 'cropVirtualBlocks' }, | 
					
						
							| 
									
										
										
										
											2019-10-24 04:40:45 +03:00
										 |  |  | 		'crop: "!virtual" ...'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// marks...
 | 
					
						
							| 
									
										
										
										
											2019-10-25 01:25:48 +03:00
										 |  |  | 	toggleMarkVirtualBlocks: ['Virtual block|Mark/Toggle $mark on $virtual blocks', | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: 'makeVirtualBlock' }, | 
					
						
							| 
									
										
										
										
											2019-10-24 04:40:45 +03:00
										 |  |  | 		'toggleMark: "virtual"'], | 
					
						
							| 
									
										
										
										
											2019-10-25 01:25:48 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// remove...
 | 
					
						
							|  |  |  | 	// XXX alias to "remove from crop/collection" ???
 | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | var VirtualBlocks =  | 
					
						
							|  |  |  | module.VirtualBlocks = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	tag: 'virtual-blocks', | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'edit', | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 	suggested: [ | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 		'ui-virtual-blocks', | 
					
						
							|  |  |  | 		'ui-virtual-blocks-edit', | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	actions: VirtualBlocksActions,  | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | var VirtualBlocksUIActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 	config: { | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 		// Threshold text length at which 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 		'virtual-text-fit-area-threshold': 100, | 
					
						
							| 
									
										
										
										
											2019-10-13 13:37:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Editable virtual block fields...
 | 
					
						
							|  |  |  | 		//
 | 
					
						
							|  |  |  | 		// XXX if we need to add types try and re-use existing editor 
 | 
					
						
							|  |  |  | 		// 		constructors in features/ui-widgets.js....
 | 
					
						
							|  |  |  | 		'virtual-text-fields': { | 
					
						
							|  |  |  | 			'Tit$le': 'name', | 
					
						
							|  |  |  | 			'Te$xt': 'text', | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__virtual_block_processors__: { | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 		// Text handler is designed to process plain or lightly 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 		// formatted text.
 | 
					
						
							|  |  |  | 		//
 | 
					
						
							|  |  |  | 		// This will:
 | 
					
						
							|  |  |  | 		// 	- replace '\n' with '<br>'
 | 
					
						
							|  |  |  | 		// 	- adjust font size to fit the image block
 | 
					
						
							|  |  |  | 		//
 | 
					
						
							|  |  |  | 		// NOTE: the processor is allowed to only modify image block 
 | 
					
						
							|  |  |  | 		// 		content, anything else would require cleanup...
 | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 		//
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 		// XXX might be a good idea to add action param to enable 
 | 
					
						
							|  |  |  | 		// 		handlers to do things like 'setup', 'cleanup', ...	
 | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 		text: function(image, dom){ | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 			if(!image.text){ | 
					
						
							|  |  |  | 				return dom } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// threshold after which we try to fill the volume...
 | 
					
						
							|  |  |  | 			var C = this.config['virtual-text-fit-area-threshold'] || 100 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// construct a basic text element...
 | 
					
						
							|  |  |  | 			var text = document.createElement('div') | 
					
						
							|  |  |  | 			text.innerHTML = image.text | 
					
						
							|  |  |  | 				.replace(/\n/g, '<br>\n') | 
					
						
							|  |  |  | 			dom[0].innerHTML = '' | 
					
						
							|  |  |  | 			dom[0].appendChild(text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// scale the text if it is small...
 | 
					
						
							|  |  |  | 			var R = dom[0].offsetHeight * 0.8 | 
					
						
							|  |  |  | 			var r = image.text.length > C ? | 
					
						
							|  |  |  | 				Math.max( | 
					
						
							|  |  |  | 					text.offsetWidth,  | 
					
						
							|  |  |  | 					text.offsetHeight,  | 
					
						
							|  |  |  | 					// keep large text blocks roughly square-ish...
 | 
					
						
							|  |  |  | 					Math.sqrt(text.scrollHeight * text.scrollWidth)) | 
					
						
							|  |  |  | 				: Math.max( | 
					
						
							|  |  |  | 					text.offsetWidth,  | 
					
						
							|  |  |  | 					text.offsetHeight,  | 
					
						
							|  |  |  | 					text.scrollHeight, | 
					
						
							|  |  |  | 					text.scrollWidth) | 
					
						
							|  |  |  | 			var s = R/r | 
					
						
							|  |  |  | 			text.style.fontSize = `${ 100*s }%` | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 			// prioritize width... 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 05:45:47 +03:00
										 |  |  | 			text.style.width = '95%' | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// justify larger blocks...
 | 
					
						
							| 
									
										
										
										
											2019-10-15 05:45:47 +03:00
										 |  |  | 			image.text.length > C | 
					
						
							|  |  |  | 				&& (text.style.textAlign = 'justify') | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return dom | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* XXX | 
					
						
							|  |  |  | 		html: function(image, dom){}, | 
					
						
							|  |  |  | 		svg: function(image, dom){}, | 
					
						
							|  |  |  | 		markdown: function(image, dom){}, | 
					
						
							|  |  |  | 		pwiki: function(image, dom){}, | 
					
						
							|  |  |  | 		//*/
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2019-10-16 00:37:52 +03:00
										 |  |  | 	// XXX add format auto-detection -- first line announce (a-la pWiki)...
 | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 	updateVirtualBlock: ['- Virtual block/', | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 		function(gid, dom, image){ | 
					
						
							|  |  |  | 			image = image || this.images[gid] || {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(image.type != 'virtual'){ | 
					
						
							|  |  |  | 				return actions.UNDEFINED } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var p = (this.__virtual_block_processors__  | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 				|| VirtualBlocksUIActions.__virtual_block_processors__ | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 				|| {}) | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 			p = p[image.format] || p['text'] | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 			return p instanceof Function ? | 
					
						
							|  |  |  | 				p.call(this, image, dom)  | 
					
						
							|  |  |  | 				: dom }], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 	metadataSection: [ | 
					
						
							|  |  |  | 		{ sortedActionPriority: 80 }, | 
					
						
							|  |  |  | 		function(make, gid, image){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			if(!image || image.type != 'virtual'){ | 
					
						
							|  |  |  | 				return } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			make.Separator() | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 			this.editVirtualBlock ? | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 				// editable... 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 				this.editVirtualBlock(make, gid, image) | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 				// view only...
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:37:45 +03:00
										 |  |  | 				: Object.entries(this.config['virtual-text-fields'] || {}) | 
					
						
							|  |  |  | 					.forEach(function([title, attr]){ | 
					
						
							|  |  |  | 						make([title +':', image[attr]]) }) | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | // NOTE: this is independent of 'virtual-blocks'...
 | 
					
						
							|  |  |  | var VirtualBlocksUI =  | 
					
						
							|  |  |  | module.VirtualBlocksUI = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	tag: 'ui-virtual-blocks', | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'ui', | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 	suggested: [ | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 		'virtual-blocks', | 
					
						
							|  |  |  | 		'ui-virtual-blocks-edit', | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	actions: VirtualBlocksUIActions,  | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 		['updateImage', | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 			function(_, gid, dom){ | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 				var image = this.images[gid] || {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// set image content...
 | 
					
						
							|  |  |  | 				if(image.type == 'virtual' && image.text){ | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 					this.updateVirtualBlock(gid, dom, image) | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// clear reused image content...
 | 
					
						
							| 
									
										
										
										
											2019-10-10 00:35:53 +03:00
										 |  |  | 				} else if(dom[0].innerHTML != ''){ | 
					
						
							|  |  |  | 					dom[0].innerHTML = '' | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}], | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | var VirtualBlocksEditUIActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 	// XXX this is a good candidate for inlineing (browse2)
 | 
					
						
							| 
									
										
										
										
											2019-10-13 13:49:02 +03:00
										 |  |  | 	// XXX should we also add a preview (preview constructor from features/metadata.js)???
 | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 	// XXX should we do a sanity check for image type???
 | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 	editVirtualBlock: ['Virtual block/$Edit...', | 
					
						
							| 
									
										
										
										
											2020-05-20 20:31:19 +03:00
										 |  |  | 		{ mode: 'cloneVirtualBlock' }, | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 		widgets.makeUIDialog(function(gid){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var _make = function(make, gid, image){ | 
					
						
							| 
									
										
										
										
											2019-10-13 13:37:45 +03:00
										 |  |  | 				var Editable = function(title, attr){ | 
					
						
							|  |  |  | 					make.Editable([title +':', image[attr] || ''], { | 
					
						
							|  |  |  | 						start_on: 'open', | 
					
						
							|  |  |  | 						edit_text: 'last', | 
					
						
							|  |  |  | 						multiline: true, | 
					
						
							|  |  |  | 						reset_on_commit: false, | 
					
						
							|  |  |  | 						editdone: function(evt, value){ | 
					
						
							|  |  |  | 							if(value == ''){ | 
					
						
							|  |  |  | 								delete image[attr] | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								image[attr] = value  | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// mark image as changed...
 | 
					
						
							|  |  |  | 							that.markChanged  | 
					
						
							|  |  |  | 								&& that.markChanged('images', [gid]) | 
					
						
							|  |  |  | 							// refresh views...
 | 
					
						
							|  |  |  | 							make.dialog.updatePreview | 
					
						
							|  |  |  | 								&& make.dialog.updatePreview() | 
					
						
							|  |  |  | 							that.refresh(gid) | 
					
						
							|  |  |  | 						}, }) } | 
					
						
							|  |  |  | 				// build the list...
 | 
					
						
							|  |  |  | 				Object.entries(that.config['virtual-text-fields'] || {}) | 
					
						
							|  |  |  | 					.forEach(function([title, attr]){ | 
					
						
							|  |  |  | 						Editable(title, attr) }) } | 
					
						
							| 
									
										
										
										
											2019-10-12 06:38:48 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// XXX should this be a more specific test???
 | 
					
						
							|  |  |  | 			return arguments[0] instanceof Function? | 
					
						
							|  |  |  | 				// inline...
 | 
					
						
							|  |  |  | 				_make.call(this, ...arguments) | 
					
						
							|  |  |  | 				// dialog...
 | 
					
						
							|  |  |  | 				: browse.makeLister(null,  | 
					
						
							|  |  |  | 					function(p, make){ | 
					
						
							|  |  |  | 						var gid = gid || that.current | 
					
						
							|  |  |  | 						var data = data || that.images[gid] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						_make(make, gid, data)  | 
					
						
							|  |  |  | 					}, { | 
					
						
							|  |  |  | 						cls: 'table-view', | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 					.close(function(){ | 
					
						
							|  |  |  | 						that.refresh(gid) }) })], | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-27 16:52:09 +03:00
										 |  |  | 	// virtual block templates...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2019-10-29 16:00:17 +03:00
										 |  |  | 	// XXX implementation vs. UI
 | 
					
						
							|  |  |  | 	// 		implementation:
 | 
					
						
							|  |  |  | 	// 			- this looks like a special collection with local .images
 | 
					
						
							|  |  |  | 	// 				- hidden?
 | 
					
						
							|  |  |  | 	// 				- can this be global or shared between indexes?
 | 
					
						
							|  |  |  | 	// 			- this can be just a list in .config or .data (global/local)
 | 
					
						
							|  |  |  | 	// 		UI:
 | 
					
						
							|  |  |  | 	// 			- this can be loaded and/or edited as a collection
 | 
					
						
							|  |  |  | 	// 			- this can be a dialog...
 | 
					
						
							| 
									
										
										
										
											2019-10-22 04:53:08 +03:00
										 |  |  | 	cloneVirtualBlockFromTemplate: ['- Virtual block/Clone from template...', | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 		function(){  | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 	saveVirtualBlockAsTemplate: ['- Virtual block/Save as template', | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 		function(gid){ | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX list existing non-blank v-blocks...
 | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 	cloneVirtualBlockFrom: ['- Virtual block/Clone...', | 
					
						
							| 
									
										
										
										
											2019-10-25 01:25:48 +03:00
										 |  |  | 		function(position){  | 
					
						
							| 
									
										
										
										
											2019-10-20 10:20:47 +03:00
										 |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2019-10-21 11:37:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-30 01:43:07 +03:00
										 |  |  | 	// XXX add alias to remove...
 | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | // NOTE: this is independent of 'virtual-blocks'...
 | 
					
						
							|  |  |  | var VirtualBlocksEditUI =  | 
					
						
							|  |  |  | module.VirtualBlocksEditUI = core.ImageGridFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	tag: 'ui-virtual-blocks-edit', | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'ui', | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 		'ui-virtual-blocks', | 
					
						
							|  |  |  | 		'virtual-blocks', | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 03:34:19 +03:00
										 |  |  | 	actions: VirtualBlocksEditUIActions,  | 
					
						
							| 
									
										
										
										
											2019-10-10 06:07:17 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-13 04:33:36 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-09 03:04:46 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |