### Install UI Component
Source: https://github.com/totaljs/uibuilder/blob/main/public/forms/components.html
Handles the installation of a UI component. It retrieves the component's ID, name, and URL from element attributes. It then updates the component's status to 'installed' and adds it to the application's schema if it's not already present. It includes an optional approval step before installation.
```JavaScript
exports.install = function(el) {
var id = el.attrd2('id');
var name = el.attrd2('name');
var url = el.attrd2('url');
var download = function() {
el.aclass('installed');
if (!app.schema.components[id]) {
app.schema.components[id] = url;
redraw = true;
}
};
if (exports.data.approve) EXEC('-approve/show', '@(Are you sure you want to import selected component "{0}"?)'.format(el.attrd2('name')), '"fas fa-cloud-download" @(Import)', download);
else download();
};
```
--------------------------------
### Total.js UI Builder - Plugin Initialization and Functions
Source: https://github.com/totaljs/uibuilder/blob/main/public/forms/templates.html
Initializes a Total.js plugin with functions for reloading, refreshing the template list, installing a selected template, downloading template data, and closing the UI builder. It handles AJAX requests, data updates, and user feedback messages.
```JavaScript
PLUGIN(function(exports) {
exports.reload = function() {
exports.refresh();
};
exports.refresh = function() {
var url = NAV.query.templates || '/templates.json';
exports.set('demos', !NAV.query.templates);
exports.ajax('GET ' + url, 'items');
SETTER('loading/hide', 1000);
};
exports.install = function(el) {
var id = ATTRD(el);
var model = exports.model;
var template = model.items.findItem('id', id);
exports.ajax('GET ' + template.template, function(response) {
response.id = Date.now().toString(36);
UIBuilder.data = response;
uibuilder_redraw();
WAIT('app', uibuilder_settings);
NUL('common.form');
});
};
exports.download = function(el) {
var id = ATTRD(el);
exports.ajax('{0}'.format(id), function(response) {
response.id = Date.now().toString(36);
UIBuilder.data = response;
uibuilder_redraw();
WAIT('app', uibuilder_settings);
NUL('common.form');
});
};
exports.close = function() {
if (!UIBuilder.data) {
if (common.iframe) {
uibuilder_close();
} else {
SETTER('message/warning', '@(You need to choose a template)');
SET('common.form', exports.name, 2000);
}
}
};
});
```
--------------------------------
### UIBuilder Directory Component Initialization
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
Initializes the UIBuilder directory component, setting up its internal structure, event listeners, and default configurations. It defines templates for rendering list items and handles initial setup like making the component non-compilable and read-only.
```javascript
COMPONENT('directory','minwidth:200;create:Create',function(self,config,cls){var cls2='.'+cls,container,timeout,icon,plus,skipreset=false,skipclear=false,ready=false,input=null,issearch=false,is=false,selectedindex=0,resultscount=0,templateE='{{ name | encode | ui_directory_helper}}',templateR='{{ name | raw}}',template='
{{ if $.checkbox}}{{ fi}}{0}
',templateraw=template.format(templateR);var regstrip=/( |<([^>]+)>)/ig;var parentclass=null,parentclass2=null,skiphide=false,skipmouse=false,customvalue,search,main;template=template.format(templateE);Thelpers.ui_directory_helper=function(val){var t=this;return self.opt.templatecompiled?self.opt.templatecompiled(this):t.template?(typeof(t.template)==='string'?t.template.indexOf('{{')===-1?t.template:Tangular.render(t.template,this):t.render(this,val)):self.opt.render?self.opt.render(this,val):val};self.template=Tangular.compile(template);self.templateraw=Tangular.compile(templateraw);self.readonly();self.singleton();self.nocompile();self.configure=function(key,value,init){if(init)return;switch(key){case'placeholder':self.find('input').prop('placeholder',value);break}};
```
--------------------------------
### UIBuilder URL Path Handling
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
A utility function to process and return a URL path, ensuring it starts with a '/' and handles potential query parameters or fragments.
```javascript
function y(e){var t,n='';return n='/'!==e.charAt(0)?-1===(t=e.indexOf('/',9))?e:e.substring(0,t):n}
```
--------------------------------
### Image Processing and Resizing
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
This section covers the image processing logic, including reading image files, getting EXIF orientation, resizing images to specified dimensions, and converting them to base64 data URLs for upload.
```javascript
self.processimage=function(file,callback){
var name=self.preparefilename(file.name.replace(/\.(ico|png|jpeg|jpg|gif|svg|webp|heic)$/i,self.opt.background==='transparent'?'.png':'.jpg'));
self.getorientation(file,function(orient){
var reader=new FileReader();
reader.onload=function(){
var img=new Image();
img.onload=function(){
if(self.opt.keeporiginal&&((img.width==self.opt.width&&img.height==self.opt.height)||(self.opt.width&&self.opt.onlylarger&&img.width<=self.opt.width)))
fetch(reader.result).then(res=>res.blob()).then(blob=>callback(name,blob));
else
self.resizeimage(img,name,callback)
};
img.crossOrigin='anonymous';
if(orient<2)
img.src=reader.result;
else
self.resetorientation(reader.result,orient,url=>img.src=url)
};
reader.readAsDataURL(file)
})
};
var resizewidth=function(w,h,size){
return Math.ceil(w*(size/h))
};
var resizeheight=function(w,h,size){
return Math.ceil(h*(size/w))
};
self.resizeimage=function(image,name,callback){
var opt=self.opt,canvas=document.createElement('canvas');
var ctx=canvas.getContext('2d');
var w=0,h=0,x=0,y=0,is=false,diff=0;
if(!opt.width)opt.width=(image.width*(opt.height/image.height))>>0;
if(!opt.height)opt.height=image.height*(opt.width/image.width);
canvas.width=opt.width;
canvas.height=opt.height;
if(opt.background!=='transparent'){
ctx.fillStyle=opt.background||'#FFFFFF';
ctx.fillRect(0,0,opt.width,opt.height)
}
if(image.width>opt.width||image.height>opt.height){
if(image.width>image.height){
w=resizewidth(image.width,image.height,opt.height);
h=opt.height;
if(wopt.width){
diff=w-opt.width;
x-=(diff/2)>>0
}
is=true
} else if(image.height>image.width){
w=opt.width;
h=resizeheight(image.width,image.height,opt.width);
if(hopt.height){
diff=h-opt.height;
y-=(diff/2)>>0
}
is=true
}
}
if(!is){
if(image.width=image.height){
w=opt.width;
h=image.height*(opt.width/image.width);
y=(opt.height/2)-(h/2)
} else {
h=opt.height;
w=(image.width*(opt.height/image.height))>>0;
x=(opt.width/2)-(w/2)
}
}
ctx.drawImage(image,x,y,w,h);
var base64=opt.background==='transparent'?canvas.toDataURL('image/png'):canvas.toDataURL('image/jpeg',(opt.quality||90)*0.01);
if(base64.length>10)
fetch(base64).then(res=>res.blob()).then(blob=>callback(name,blob))
};
self.getorientation=function(file,callback){
var reader=new FileReader();
reader.onload=function(e){
var view=new DataView(e.target.result);
if(view.getUint16(0,false)!=0xFFD8)
return callback(-2);
var length=view.byteLength,offset=2;
while(offset @(Your Total.js Enterprise Account expires on) {{ value.dtexpire | format('[date]') }} @(Warn about component installation)
{{ foreach n in value }} {{ if n.name && n.name !== '0' }}
{{ n.name }}
{{ fi }}
{{ foreach m in n.items }}
@(Read me){{ if m.newupdate }}@(update){{ fi }}{{ if m.enterprise }}Enterprise{{ fi }}{{ m.name }}
{{ end }}
{{ end }}
```
--------------------------------
### UIBuilder Brick Initialization and Rendering
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
This snippet outlines the process of initializing UIBuilder bricks, parsing their attributes, and managing their children. It details how component configurations are loaded, how coordinates and z-index are set, and how the brick's structure is prepared for rendering, including handling nested components and script-based configurations.
```javascript
c.config=(i.getAttribute('config')||'').parseConfig(),c.x=i.getAttribute('x')||'',c.x=c.x?c.x.parseInt():void 0,c.y=i.getAttribute('y')||'',c.y=c.y?c.y.parseInt():void 0,c.zindex=i.getAttribute('zindex')||'',c.zindex=c.zindex?c.zindex.parseInt():void 0,c.children=[],c.iscontainer='UIBUILDER-CONTAINER'===i.parentNode.tagName;for(var l of i.children)if('SCRIPT'===l.tagName){var f=PARSE(l.innerHTML);if(f)for(var u in f)c.config[u]=f[u]}var p=i.getAttribute('path');p&&(c.config.path=p),a.push(i),h.components[c.component];h.components[c.component]||(h.components[c.component]=i.getAttribute('source')||'@')}else W.console&&W.console.warn(b,'Invalid brick declaration.',i)}n&&!s.length&&(e.push(t=[]),e=t);for(o of a){var d=o.$uibuilderbrick;if(e.push(d),o.children.length){let e=d.children;d.iscontainer||(e=[],d.children.push(e)),v(e,o)}}for(r of s){var m=[];e.push(m),v(m,r)}});v(h.children,n,!0),UIBuilder.build(n,h,function(e){var t=n.getAttribute('load');(t=t&&GET(t))&&'function'==typeof t&&t(e)})}}
```
--------------------------------
### UIBuilder Rebind Functionality
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
Handles the re-binding of UI components. It identifies components with paths starting with '@', groups them by their target ID, and updates their binding information.
```javascript
function f(e){var t,n={},i={},o=!1;e.$rebindtimeout=null;for(r of e.instances)r.config.path&&'@'===r.config.path.charAt(0)&&(t=r.config.path.substring(1))!=r.id&&(n[t]?n[t].push(r):n[t]=[r],i[r.id]=t,o=!0);if(o)for(var r of e.instances)r.binded=n[r.id]||null,r.binder=i[r.id]?e.instances.findItem('id',i[r.id]):null}
```
--------------------------------
### Initialize and Manage UI Builder Instances
Source: https://github.com/totaljs/uibuilder/blob/main/public/render.txt
This code iterates through UI Builder instances, manages their z-index, collects inputs and outputs, and handles application readiness and callbacks. It also includes logic for forkable components and emitting application-level events.
```javascript
var e,t,n,i,o,r,s,a,l,f,u,c,p,h,d,g,m,v,y,b,_;m.list=[],m.zindex=1;for(var e of m.instances)if(e.dom.parentNode){var t=e.component,n=(t.floating&&(m.zindex=(e.element.css('z-index')||'').parseInt(),m.zindex<=0)&&(m.zindex=1),e.inputs||t.inputs),i=e.config.name||t.name;if(m.list&&m.list.push({id:e.id,componentid:t.id,name:i,icon:t.icon,color:t.color}),n)for(var o of n)m.inputs.push({id:e.id+'_'+o.id,ref:o.id,name:i+(1