PageSourceSearch

https://voenchast.ru/bitrix/js/fileman/html_editor/html-snippets.js

js voenchast.ru collected 2026-10-09 22:40:50 UTC 24,360 bytes, 945 lines download raw bytes

1/**
2 * Bitrix HTML Editor 3.0
3 * Date: 24.04.13
4 * Time: 4:23
5 *
6 * Snippets class
7 */
8(function()
9{
10function __runsnips()
11{
12	function BXEditorSnippets(editor)
13	{
14		this.editor = editor;
15		this.listLoaded = false;
16		this.snippets = this.editor.config.snippets;
17		this.HandleList();
18		this.Init();
19	}
20
21	BXEditorSnippets.prototype = {
22		Init: function()
23		{
24			BX.addCustomEvent(this.editor, "OnApplySiteTemplate", BX.proxy(this.OnTemplateChanged, this));
25		},
26
27		SetSnippets: function(snippets)
28		{
29			this.snippets =
30				this.editor.config.snippets =
31					this.editor.snippetsTaskbar.snippets = snippets;
32			this.HandleList();
33		},
34
35		GetList: function()
36		{
37			return this.snippets[this.editor.GetTemplateId()];
38		},
39
40		HandleList: function()
41		{
42			var
43				i,
44				items = this.GetList().items;
45			if (items)
46			{
47				for (i in items)
48				{
49					if (items.hasOwnProperty(i))
50					{
51						items[i].key = items[i].path.replace('/', ',');
52					}
53				}
54			}
55		},
56
57		ReloadList: function(clearCache)
58		{
59			this.editor.snippetsTaskbar.ClearSearchResult();
60			var _this = this;
61			this.editor.Request({
62				getData: this.editor.GetReqData('load_snippets_list',
63					{
64						site_template: this.editor.GetTemplateId(),
65						clear_cache: clearCache ? 'Y' : 'N'
66					}
67				),
68				handler: function(res)
69				{
70					if (res.result)
71					{
72						_this.SetSnippets(res.snippets);
73						_this.RebuildAll();
74					}
75				}
76			});
77		},
78
79		FetchPlainListOfCategories: function(list, level, result)
80		{
81			var i, l = list.length;
82			for (i = 0; i < l; i++)
83			{
84				result.push({
85					level: level,
86					key: list[i].key,
87					section: list[i].section
88				});
89
90				if (list[i].children && list[i].children.length > 0)
91				{
92					this.FetchPlainListOfCategories(list[i].children, level + 1, result);
93				}
94			}
95		},
96
97		AddNewCategory: function(params)
98		{
99			var _this = this;
100			this.editor.Request({
101				getData: this.editor.GetReqData('snippet_add_category',
102					{
103						site_template: this.editor.GetTemplateId(),
104						category_name: params.name,
105						category_parent: params.parent
106					}
107				),
108				handler: function(res)
109				{
110					if (res.result)
111					{
112						_this.SetSnippets(res.snippets);
113						_this.RebuildAll();
114					}
115				}
116			});
117		},
118
119		RemoveCategory: function(params)
120		{
121			var _this = this;
122			this.editor.Request({
123				getData: this.editor.GetReqData('snippet_remove_category',
124					{
125						site_template: this.editor.GetTemplateId(),
126						category_path: params.path
127					}
128				),
129				handler: function(res)
130				{
131					if (res.result)
132					{
133						_this.SetSnippets(res.snippets);
134						_this.RebuildAll();
135					}
136				}
137			});
138		},
139
140		RenameCategory: function(params)
141		{
142			var _this = this;
143			this.editor.Request({
144				getData: this.editor.GetReqData('snippet_rename_category',
145					{
146						site_template: this.editor.GetTemplateId(),
147						category_path: params.path,
148						category_new_name: params.newName
149					}
150				),
151				handler: function(res)
152				{
153					if (res.result)
154					{
155						_this.SetSnippets(res.snippets);
156						_this.RebuildAll();
157					}
158				}
159			});
160		},
161
162		SaveSnippet: function(params)
163		{
164			var _this = this;
165			this.editor.Request({
166				postData: this.editor.GetReqData('edit_snippet',
167					{
168						site_template: this.editor.GetTemplateId(),
169						path: params.path.replace(',', '/'),
170						name: params.name,
171						code: params.code,
172						description: params.description,
173						current_path: params.currentPath
174					}
175				),
176				handler: function(res)
177				{
178					if (res.result)
179					{
180						_this.SetSnippets(res.snippets);
181						_this.RebuildAll();
182					}
183				}
184			});
185		},
186
187		RemoveSnippet: function(params)
188		{
189			var _this = this;
190			this.editor.Request({
191				getData: this.editor.GetReqData('remove_snippet',
192					{
193						site_template: this.editor.GetTemplateId(),
194						path: params.path.replace(',', '/')
195					}
196				),
197				handler: function(res)
198				{
199					if (res.result)
200					{
201						_this.SetSnippets(res.snippets);
202						_this.RebuildAll();
203					}
204				}
205			});
206		},
207
208		RebuildAll: function()
209		{
210			var snippetsCategories = this.editor.GetDialog('snippetsCategories');
211			if (snippetsCategories && snippetsCategories.IsOpen())
212			{
213				snippetsCategories.DisplayAddForm(false);
214				snippetsCategories.BuildTree(this.GetList().groups);
215			}
216
217			// Build structure
218			if (this.snippets[this.editor.GetTemplateId()] && this.editor.snippetsTaskbar)
219			{
220				this.editor.snippetsTaskbar.BuildTree(this.snippets[this.editor.GetTemplateId()].groups, this.snippets[this.editor.GetTemplateId()].items);
221			}
222
223			var editSnippet = this.editor.GetDialog('editSnippet');
224			if (editSnippet && editSnippet.IsOpen())
225			{
226				editSnippet.SetCategories();
227			}
228		},
229
230		OnTemplateChanged: function()
231		{
232			this.ReloadList(false);
233		}
234	};
235
236	function SnippetsControl(editor)
237	{
238		// Call parrent constructor
239		SnippetsControl.superclass.constructor.apply(this, arguments);
240
241		this.id = 'snippets';
242		this.snippets = this.editor.config.snippets;
243		this.templateId = this.editor.templateId;
244		this.title = BX.message('BXEdSnippetsTitle');
245		this.searchPlaceholder = BX.message('BXEdSnipSearchPlaceHolder');
246		this.uniqueId = 'taskbar_' + this.editor.id + '_' + this.id;
247
248		this.Init();
249	}
250
251	BX.extend(SnippetsControl, window.BXHtmlEditor.Taskbar);
252
253	SnippetsControl.prototype.Init = function()
254	{
255		this.BuildSceleton();
256
257		// Build structure
258		if (this.snippets[this.templateId])
259		{
260			this.BuildTree(this.snippets[this.templateId].groups, this.snippets[this.templateId].items);
261		}
262
263		var _this = this;
264		_this.editor.phpParser.AddBxNode('snippet_icon',
265			{
266				Parse: function(params)
267				{
268					return params.code || '';
269				}
270			}
271		);
272	};
273
274	SnippetsControl.prototype.GetMenuItems = function()
275	{
276		var _this = this;
277
278		return [
279			{
280				text : BX.message('BXEdAddSnippet'),
281				title : BX.message('BXEdAddSnippet'),
282				className : "",
283				onclick: function()
284				{
285					_this.editor.GetDialog('editSnippet').Show();
286					BX.PopupMenu.destroy(_this.uniqueId + "_menu");
287				}
288			},
289			{
290				text : BX.message('RefreshTaskbar'),
291				title : BX.message('RefreshTaskbar'),
292				className : "",
293				onclick: function()
294				{
295					_this.editor.snippets.ReloadList(true);
296					BX.PopupMenu.destroy(_this.uniqueId + "_menu");
297				}
298			},
299			{
300				text : BX.message('BXEdManageCategories'),
301				title : BX.message('BXEdManageCategories'),
302				className : "",
303				onclick: function()
304				{
305					_this.editor.GetDialog('snippetsCategories').Show();
306					BX.PopupMenu.destroy(_this.uniqueId + "_menu");
307				}
308			}
309		];
310	};
311
312	SnippetsControl.prototype.HandleElementEx = function(wrap, dd, params)
313	{
314		this.editor.SetBxTag(dd, {tag: "snippet_icon", params: params});
315		wrap.title = params.description || params.title;
316
317		var editBut = wrap.appendChild(BX.create("SPAN", {props: {className: "bxhtmled-right-side-item-edit-btn", title: BX.message('BXEdSnipEdit')}}));
318		this.editor.SetBxTag(editBut, {tag: "_snippet", params: params});
319
320		BX.bind(editBut, 'mousedown', BX.proxy(this.EditSnippet, this));
321	};
322
323	SnippetsControl.prototype.EditSnippet = function(e)
324	{
325		var target = e.target || e.srcElement;
326
327		function _editDeactivate()
328		{
329			BX.removeClass(target, 'bxhtmled-right-side-item-edit-btn-active');
330			BX.unbind(document, 'mouseup', _editDeactivate);
331		}
332
333		BX.addClass(target, 'bxhtmled-right-side-item-edit-btn-active');
334		BX.bind(document, 'mouseup', _editDeactivate);
335
336		this.editor.GetDialog('editSnippet').Show(target);
337		return BX.PreventDefault(e);
338	};
339
340	SnippetsControl.prototype.BuildTree = function(sections, elements)
341	{
342		// Call parent method
343		SnippetsControl.superclass.BuildTree.apply(this, arguments);
344		if ((!sections || sections.length == 0) && (!elements || elements.length == 0))
345		{
346			this.pTreeCont.appendChild(BX.create('DIV', {props: {className: 'bxhtmled-no-snip'}, text: BX.message('BXEdSnipNoSnippets')}));
347		}
348	};
349
350	function EditSnippetDialog(editor, params)
351	{
352		params = params || {};
353		params.id = 'bx_edit_snippet';
354		params.width =  600;
355		this.zIndex = 3007;
356		this.id = 'edit_snippet';
357
358		// Call parrent constructor
359		EditSnippetDialog.superclass.constructor.apply(this, [editor, params]);
360		this.SetContent(this.Build());
361		BX.addClass(this.oDialog.DIV, "bx-edit-snip-dialog");
362		BX.addCustomEvent(this, "OnDialogSave", BX.proxy(this.Save, this));
363	}
364	BX.extend(EditSnippetDialog, window.BXHtmlEditor.Dialog);
365
366	EditSnippetDialog.prototype.Save = function()
367	{
368		this.editor.snippets.SaveSnippet(
369			{
370				path: this.pCatSelect.value,
371				name: this.pName.value,
372				code: this.pCode.value,
373				description: this.pDesc.value,
374				currentPath: this.currentPath
375			}
376		);
377	};
378
379	EditSnippetDialog.prototype.Build = function()
380	{
381		this.pCont = BX.create('DIV', {props: {className: 'bxhtmled-edit-snip-cnt'}});
382
383		function addRow(tbl, c1Par, bAdditional)
384		{
385			var r, c1, c2;
386
387			r = tbl.insertRow(-1);
388			if (bAdditional)
389			{
390				r.className = 'bxhtmled-add-row';
391			}
392
393			c1 = r.insertCell(-1);
394			c1.className = 'bxhtmled-left-c';
395
396			if (c1Par && c1Par.label)
397			{
398				c1.appendChild(BX.create('LABEL', {props: {className: c1Par.required ? 'bxhtmled-req' : ''},text: c1Par.label})).setAttribute('for', c1Par.id);
399			}
400
401			c2 = r.insertCell(-1);
402			c2.className = 'bxhtmled-right-c';
403			return {row: r, leftCell: c1, rightCell: c2};
404		}
405
406		this.arTabs = [
407			{
408				id: 'base',
409				name: BX.message('BXEdSnipBaseSettings')
410			},
411			{
412				id: 'additional',
413				name: BX.message('BXEdSnipAddSettings')
414			}
415		];
416
417
418		var res = this.BuildTabControl(this.pCont, this.arTabs);
419		this.arTabs = res.tabs;
420
421		// Base params
422		var
423			_this = this,
424			r, c,
425			pBaseTbl = BX.create('TABLE', {props: {className: 'bxhtmled-dialog-tbl'}}),
426			pAddTbl = BX.create('TABLE', {props: {className: 'bxhtmled-dialog-tbl'}});
427
428		// Name
429		r = addRow(pBaseTbl, {label: BX.message('BXEdSnipName') + ':', id: this.id + '-name', required: true});
430		this.pName = r.rightCell.appendChild(BX.create('INPUT', {props:
431		{
432			type: 'text',
433			id: this.id + '-name',
434			placeholder: BX.message('BXEdSnipNamePlaceHolder')
435		}}));
436
437		// Code
438		r = addRow(pBaseTbl, {label: BX.message('BXEdSnipCode') + ':', id: this.id + '-code', required: true});
439		this.pCode = r.rightCell.appendChild(BX.create('TEXTAREA', {
440			props:
441			{
442				id: this.id + '-code',
443				placeholder: BX.message('BXEdSnipCodePlaceHolder')
444			},
445			style:
446			{
447				height: '250px'
448			}
449		}));
450		this.arTabs[0].cont.appendChild(pBaseTbl);
451
452		// Category
453		r = addRow(pAddTbl, {label: BX.message('BXEdSnipCategory') + ':', id: this.id + '-category'});
454		this.pCatSelect = r.rightCell.appendChild(BX.create('SELECT', {
455			props: {
456				id: this.id + '-category'
457			},
458			style: {
459				maxWidth: '280px'
460			}
461		}));
462		this.pCatManageBut = r.rightCell.appendChild(BX.create('INPUT', {props:
463		{
464			className: 'bxhtmled-manage-cat',
465			type: 'button',
466			value: '...',
467			title: BX.message('BXEdManageCategories')
468		}}));
469		this.pCatManageBut.onclick = function()
470		{
471			_this.editor.GetDialog('snippetsCategories').Show();
472		};
473
474		// Description
475		r = addRow(pAddTbl, {label: BX.message('BXEdSnipDescription') + ':', id: this.id + '-hint'});
476		this.pDesc = r.rightCell.appendChild(BX.create('TEXTAREA', {props:
477		{
478			id: this.id + '-hint',
479			placeholder: BX.message('BXEdSnipDescriptionPlaceholder')
480		}}));
481		this.arTabs[1].cont.appendChild(pAddTbl);
482
483		// Delete button
484		r = BX.adjust(pAddTbl.insertRow(-1), {style: {display: 'none'}});
485		c = BX.adjust(r.insertCell(-1), {props: {className: 'bxhtmled--centr-c'}, attrs: {colsPan: 2}});
486		c.appendChild(BX.create("INPUT", {
487			props:{className: '', type: 'button', value: BX.message('BXEdSnipRemove')},
488			events: {
489				'click' : function()
490				{
491					if (confirm(BX.message('BXEdSnipRemoveConfirm')))
492					{
493						_this.editor.snippets.RemoveSnippet({path: _this.currentPath});
494						_this.Close();
495					}
496				}
497			}
498		}));
499		this.delSnipRow = r;
500
501		return this.pCont;
502	};
503
504	EditSnippetDialog.prototype.Show = function(snippetNode)
505	{
506		this.SetTitle(BX.message('BXEdEditSnippetDialogTitle'));
507		this.SetCategories();
508
509		var
510			params = {},
511			bxTag = this.editor.GetBxTag(snippetNode),
512			bNew = !bxTag || !bxTag.tag;
513
514		if (!bNew)
515		{
516			params = bxTag.params;
517			this.currentPath = (params.path == '' ? '' : params.path.replace(',', '/') + '/') + params.name;
518			this.delSnipRow.style.display = '';
519		}
520		else
521		{
522			this.currentPath = '';
523			this.delSnipRow.style.display = 'none';
524		}
525
526		this.pName.value = params.title || '';
527		this.pCode.value = params.code || '';
528		this.pDesc.value = params.description || '';
529		this.pCatSelect.value = params.key || '';
530
531		// Call parrent Dialog.Show()
532		EditSnippetDialog.superclass.Show.apply(this, arguments);
533	};
534
535	EditSnippetDialog.prototype.SetCategories = function()
536	{
537		// Clear select
538		this.pCatSelect.options.length = 0;
539		this.pCatSelect.options.add(new Option(BX.message('BXEdSnippetsTitle'), '', true, true));
540
541		var
542			name, delim = ' . ', j, i,
543			plainList = [],
544			list = this.editor.snippetsTaskbar.GetSectionsTreeInfo();
545
546		this.editor.snippets.FetchPlainListOfCategories(list, 1, plainList);
547
548		for (i = 0; i < plainList.length; i++)
549		{
550			name = '';
551			for (j = 0; j < plainList[i].level; j++)
552			{
553				name += delim;
554			}
555			name += plainList[i].section.name;
556
557			this.pCatSelect.options.add(new Option(name, plainList[i].key, false, false));
558		}
559	};
560
561	function SnippetsCategoryDialog(editor, params)
562	{
563		params = params || {};
564		params.id = 'bx_snippets_cats';
565		//params.height = 600;
566		params.width =  400;
567		params.zIndex = 3010;
568
569		this.id = 'snippet_categories';
570
571		// Call parrent constructor
572		SnippetsCategoryDialog.superclass.constructor.apply(this, [editor, params]);
573		this.SetContent(this.Build());
574
575		this.oDialog.ClearButtons();
576		this.oDialog.SetButtons([this.oDialog.btnClose]);
577
578		BX.addClass(this.oDialog.DIV, "bx-edit-snip-cat-dialog");
579		//BX.addCustomEvent(this, "OnDialogSave", BX.proxy(this.Save, this));
580	}
581	BX.extend(SnippetsCategoryDialog, window.BXHtmlEditor.Dialog);
582
583	SnippetsCategoryDialog.prototype.Save = function()
584	{
585	};
586
587	SnippetsCategoryDialog.prototype.Build = function()
588	{
589		this.pCont = BX.create('DIV', {props: {className: 'bxhtmled-snip-cat-cnt'}});
590
591		// Add category button & wrap
592		this.pAddCatWrap = this.pCont.appendChild(BX.create('DIV', {props: {className: 'bxhtmled-snip-cat-add-wrap'}}));
593		this.pAddCatBut = this.pAddCatWrap.appendChild(BX.create('SPAN', {props: {className: 'bxhtmled-snip-cat-add-but'}, text: BX.message('BXEdSnipCatAdd')}));
594		BX.bind(this.pAddCatBut, 'click', BX.proxy(this.DisplayAddForm, this));
595
596		var tbl = this.pAddCatWrap.appendChild(BX.create('TABLE', {props: {className: 'bxhtmled-snip-cat-add-tbl'}}));
597		var r, c;
598		r = tbl.insertRow(-1);
599		c = r.insertCell(-1);
600		c.className = 'bxhtmled-left-c';
601		c.appendChild(BX.create('LABEL', {props: {className: 'bxhtmled-req'}, attrs: {'for': this.id + '-cat-name'}, text: BX.message('BXEdSnipCatAddName') + ':'}));
602
603		c = r.insertCell(-1);
604		c.className = 'bxhtmled-right-c';
605		this.pCatName = c.appendChild(BX.create('INPUT', {props:
606		{
607			type: 'text',
608			id: this.id + '-cat-name'
609		}}));
610
611		r = tbl.insertRow(-1);
612		c = r.insertCell(-1);
613		c.className = 'bxhtmled-left-c';
614		c.appendChild(BX.create('LABEL', {props: {className: 'bxhtmled-req'}, attrs: {'for': this.id + '-cat-par'}, text: BX.message('BXEdSnipParCategory') + ':'}));
615
616		c = r.insertCell(-1);
617		c.className = 'bxhtmled-right-c';
618		this.pCatPar = c.appendChild(BX.create('SELECT', {props:{id: this.id + '-cat-par'}}));
619
620		r = tbl.insertRow(-1);
621		c = r.insertCell(-1);
622		c.colSpan = 2;
623		c.style.textAlign = 'center';
624
625		this.pSaveCat = c.appendChild(BX.create('INPUT', {props:
626		{
627			type: 'button',
628			className: 'adm-btn-save bxhtmled-snip-save-but',
629			value: BX.message('BXEdSnipCatAddBut')
630		}}));
631		BX.bind(this.pSaveCat, 'click', BX.proxy(this.AddNewCategory, this));
632
633		// Category List
634		this.pCatListWrap = this.pCont.appendChild(BX.create('DIV', {props: {className: 'bxhtmled-snip-cat-list-wrap'}}));
635
636		return this.pCont;
637	};
638
639	SnippetsCategoryDialog.prototype.AddNewCategory = function()
640	{
641		this.editor.snippets.AddNewCategory({
642			name: this.pCatName.value,
643			parent: this.pCatPar.value,
644			siteTemplate: ''
645		});
646	};
647
648
649	SnippetsCategoryDialog.prototype.DisplayAddForm = function(bShow)
650	{
651		if (this.animation)
652			this.animation.stop();
653
654		if (bShow !== true && bShow !== false)
655			bShow = !this.bAddCatOpened;
656
657		bShow = bShow !== false;
658
659		if (this.bAddCatOpened !== bShow)
660		{
661			if (bShow)
662			{
663				//jsDD.Disable();
664				this.DisableKeyCheck();
665				BX.bind(this.pCatName, 'keydown', BX.proxy(this.AddCatKeydown, this));
666
667				this.SetParentCategories();
668				this.animationStartHeight = 25;
669				this.animationEndHeight = 160;
670				BX.focus(this.pCatName);
671			}
672			else
673			{
674				//jsDD.Enable();
675				this.EnableKeyCheck();
676				BX.unbind(this.pCatName, 'keydown', BX.proxy(this.AddCatKeydown, this));
677				this.animationStartHeight = 160;
678				this.animationEndHeight = 25;
679			}
680
681			var _this = this;
682			this.animation = new BX.easing({
683				duration : 300,
684				start : {height: this.animationStartHeight},
685				finish : {height: this.animationEndHeight},
686				transition : BX.easing.makeEaseOut(BX.easing.transitions.quart),
687
688				step : function(state)
689				{
690					_this.pAddCatWrap.style.height = state.height + 'px';
691				},
692
693				complete : BX.proxy(function()
694				{
695					this.animation = null;
696				}, this)
697			});
698
699			this.animation.animate();
700			this.bAddCatOpened = bShow;
701		}
702		this.ResetAddCategoryForm();
703	};
704
705	SnippetsCategoryDialog.prototype.SetParentCategories = function()
706	{
707		// Clear select
708		this.pCatPar.options.length = 0;
709		this.pCatPar.options.add(new Option(BX.message('BXEdSnippetsTitle'), '', true, true));
710
711		var
712			name, delim = ' . ', j, i,
713			plainList = [],
714			list = this.editor.snippetsTaskbar.GetSectionsTreeInfo();
715
716		this.editor.snippets.FetchPlainListOfCategories(list, 1, plainList);
717
718		for (i = 0; i < plainList.length; i++)
719		{
720			if (plainList[i].level < 2)
721			{
722				name = '';
723				for (j = 0; j < plainList[i].level; j++)
724				{
725					name += delim;
726				}
727				name += plainList[i].section.name;
728
729				this.pCatPar.options.add(new Option(name, plainList[i].key, false, false));
730			}
731		}
732	};
733
734	SnippetsCategoryDialog.prototype.Show = function()
735	{
736		this.SetTitle(BX.message('BXEdManageCategoriesTitle'));
737
738		this.BuildTree(this.editor.snippets.GetList().groups);
739		this.bAddCatOpened = false;
740		this.pAddCatWrap.style.height = '';
741
742		// Call parrent Dialog.Show()
743		SnippetsCategoryDialog.superclass.Show.apply(this, arguments);
744	};
745
746	SnippetsCategoryDialog.prototype.BuildTree = function(sections)
747	{
748		BX.cleanNode(this.pCatListWrap);
749		this.catIndex = {};
750		//this.sections = [];
751		for (var i = 0; i < sections.length; i++)
752		{
753			this.BuildCategory(sections[i]);
754		}
755	};
756
757	SnippetsCategoryDialog.prototype.BuildCategory = function(section)
758	{
759		var
760			_this = this,
761			parentCont = this.GetCategoryContByPath(section.path),
762			pGroup = BX.create("DIV", {props: {className: "bxhtmled-tskbr-sect-outer"}}),
763			pGroupTitle = pGroup.appendChild(BX.create("DIV", {props: {className: "bxhtmled-tskbr-sect"}})),
764			icon = pGroupTitle.appendChild(BX.create("SPAN", {props: {className: "bxhtmled-tskbr-sect-icon bxhtmled-tskbr-sect-icon-open"}})),
765			title = pGroupTitle.appendChild(BX.create("SPAN", {props: {className: "bxhtmled-tskbr-sect-title"}, text: section.title || section.name})),
766			renameInput = pGroupTitle.appendChild(BX.create("INPUT", {props: {
767				type: 'text',
768				className: "bxhtmled-tskbr-name-input"
769			}})),
770			childCont = pGroup.appendChild(BX.create("DIV", {props: {className: "bxhtmled-tskb-child"}, style: {display: "block"}})),
771			pIconEdit = pGroupTitle.appendChild(BX.create("SPAN", {props: {className: "bxhtmled-right-side-item-edit-btn", title: BX.message('BXEdSnipCatEdit')}})),
772			pIconDel = pGroupTitle.appendChild(BX.create("SPAN", {props: {className: "bxhtmled-right-side-item-del-btn", title: BX.message('BXEdSnipCatDelete')}}));
773
774		BX.bind(pIconDel, 'mousedown', BX.proxy(this.DisableDD(), this));
775		BX.bind(pIconEdit, 'mousedown', BX.proxy(this.DisableDD(), this));
776		BX.bind(renameInput, 'mousedown', BX.proxy(this.DisableDD(), this));
777
778		// Drop category
779		BX.bind(pIconDel, 'click', function()
780			{
781				if (confirm(BX.message('BXEdDropCatConfirm')))
782				{
783					var path = section.path == '' ? section.name : section.path + '/' + section.name;
784					_this.editor.snippets.RemoveCategory({path: path});
785				}
786			}
787		);
788
789		// Rename category
790		BX.bind(pIconEdit, 'click', function()
791			{
792				_this.ShowRename(true, section, renameInput, pGroupTitle);
793			}
794		);
795
796		childCont.style.display = 'block';
797
798		var key = section.path == '' ? section.name : section.path + ',' + section.name;
799		var depth = section.path == '' ? 0 : 1;
800
801		var sect = {
802			key: key,
803			children: [],
804			section: section
805		};
806
807		this.catIndex[key] = {
808			icon: icon,
809			outerCont: pGroup,
810			cont: pGroupTitle,
811			childCont: childCont,
812			sect: sect
813		};
814
815		if (depth > 0)
816		{
817			BX.addClass(pGroupTitle, "bxhtmled-tskbr-sect-" + depth);
818			BX.addClass(icon, "bxhtmled-tskbr-sect-icon-" + depth);
819		}
820
821		parentCont.appendChild(pGroup);
822	};
823
824	SnippetsCategoryDialog.prototype.ShowRename = function(bShow, section, renameInput, pGroupTitle)
825	{
826		bShow = bShow !== false;
827		if (bShow)
828		{
829			BX.addClass(pGroupTitle, 'bxhtmled-tskbr-sect-rename');
830			this.currentRenamedCat = {
831				section: section,
832				renameInput: renameInput,
833				pGroupTitle: pGroupTitle
834			};
835			renameInput.value = section.name;
836			//jsDD.Disable();
837			this.DisableKeyCheck();
838			BX.bind(renameInput, 'keydown', BX.proxy(this.RenameKeydown, this));
839			BX.focus(renameInput);
840			renameInput.select();
841		}
842		else
843		{
844			BX.removeClass(pGroupTitle, 'bxhtmled-tskbr-sect-rename');
845			BX.unbind(renameInput, 'keydown', BX.proxy(this.RenameKeydown, this));
846			//jsDD.Enable();
847			this.EnableKeyCheck();
848			this.currentRenamedCat = false;
849		}
850	};
851
852	SnippetsCategoryDialog.prototype.RenameKeydown = function(e)
853	{
854		if (e && this.currentRenamedCat)
855		{
856			if (e.keyCode == this.editor.KEY_CODES['escape'])
857			{
858				this.ShowRename(false, this.currentRenamedCat.section, this.currentRenamedCat.renameInput, this.currentRenamedCat.pGroupTitle);
859				BX.PreventDefault(e);
860			}
861			else if (e.keyCode == this.editor.KEY_CODES['enter'])
862			{
863				var
864					newName = BX.util.trim(this.currentRenamedCat.renameInput.value),
865					section = this.currentRenamedCat.section,
866					path = section.path == '' ? section.name : section.path + '/' + section.name;
867
868				if (newName !== '')
869				{
870					this.editor.snippets.RenameCategory(
871					{
872						path: path,
873						newName: newName
874					});
875				}
876				this.ShowRename(false, this.currentRenamedCat.section, this.currentRenamedCat.renameInput, this.currentRenamedCat.pGroupTitle);
877				BX.PreventDefault(e);
878			}
879		}
880	};
881
882	SnippetsCategoryDialog.prototype.AddCatKeydown = function(e)
883	{
884		if (e && this.bAddCatOpened)
885		{
886			if (e.keyCode == this.editor.KEY_CODES['escape'])
887			{
888				this.DisplayAddForm(false);
889				BX.PreventDefault(e);
890			}
891			else if (e.keyCode == this.editor.KEY_CODES['enter'])
892			{
893				this.AddNewCategory();
894				BX.PreventDefault(e);
895			}
896		}
897	};
898
899	SnippetsCategoryDialog.prototype.DisableDD = function()
900	{
901		jsDD.Disable();
902		BX.bind(document, 'mouseup', BX.proxy(this.EnableDD, this));
903	};
904
905	SnippetsCategoryDialog.prototype.EnableDD = function()
906	{
907		jsDD.Enable();
908		BX.unbind(document, 'mouseup', BX.proxy(this.EnableDD, this));
909	};
910
911	SnippetsCategoryDialog.prototype.OnDragFinish = function()
912	{
913	};
914
915	SnippetsCategoryDialog.prototype.GetCategoryContByPath = function(path)
916	{
917		if (path == '' || !this.catIndex[path])
918		{
919			return this.pCatListWrap;
920		}
921		else
922		{
923			return this.catIndex[path].childCont;
924		}
925	};
926
927	SnippetsCategoryDialog.prototype.ResetAddCategoryForm = function(path)
928	{
929		this.pCatName.value = '';
930		this.pCatPar.value = '';
931	};
932
933
934	window.BXHtmlEditor.SnippetsControl = SnippetsControl;
935	window.BXHtmlEditor.BXEditorSnippets = BXEditorSnippets;
936	window.BXHtmlEditor.dialogs.editSnippet = EditSnippetDialog;
937	window.BXHtmlEditor.dialogs.snippetsCategories = SnippetsCategoryDialog;
938}
939
940	if (window.BXHtmlEditor && window.BXHtmlEditor.dialogs)
941		__runsnips();
942	else
943		BX.addCustomEvent(window, "OnEditorBaseControlsDefined", __runsnips);
944
945})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.