qcobjects-docs
Version:
The official app and website for documentation of QCObjects
1,139 lines (890 loc) • 120 kB
Markdown

[](https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt) [](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects?ref=badge_shield) [](https://www.jsdelivr.com/package/npm/qcobjects) [](https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode) [](https://qcobjects.readthedocs.io/?badge=latest) [](https://github.com/QuickCorp/QCObjects/releases/) [](https://github.com/QuickCorp/QCObjects) [](https://badge.fury.io/js/qcobjects)   [](CODE_OF_CONDUCT.md)
[](https://www.patreon.com/join/qcobjects?)
[](https://www.producthunt.com/posts/qcobjects?utm_source=badge-review&utm_medium=badge&utm_souce=badge-qcobjects#discussion-body)
# QCObjects
------------------------------------
Welcome to [QCObjects](https://qcobjects.dev). An Open-source framework that empowers full-stack developers to make micro-services and micro-frontends into an N-Tier architecture.
With QCObjects devlopers are also able to code front-end and back-end together using a common syntax in pure JavaScript. It is cross-browser, cross-platform and cross-frame.
Install it, make a textfield or a navigate home functionality, all in just one step.
[QCObjects is being featured by British Herald as today, the most advanced framework for modern software development.](https://britishherald.com/qcobjects-the-first-world-class-tech-framework-made-in-south-america-is-meant-to-make-developers-happier-while-they-code/)
This document is the Main Reference Documentation!
This repository and readme is hosted at [https://qcobjects.dev](https://qcobjects.dev)
Check out the official page of [QCObjects](https://qcobjects.com) at https://qcobjects.com
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to info@quickcorp.cl.
**Contributors are welcome!**
You can contribute to [QCObjects](https://qcobjects.dev) following the set of guidelines expressed in the file [CONTRIBUTING.md](CONTRIBUTING.md)
# The meaning of the name QCObjects (Do not forget the Q)
Often, some people is confusing **QCObjects** name with **CObjects** (perhaps some day it changes, who knows...) but the Q has an important meaning: It means Quick! What the complete name QCObjects does mean is **Quick Components and Objects**, and that is why the Q, C, O letters are capitalized.
# QCObjects Explainer Video
For those who have no time to read all of this today, here is a small video that explains what QCObjects is and what can be done with it.
[](https://www.youtube.com/watch?v=D0rftABPGvQ "QCObjects Explainer Video")
_________________________
# Table of Contents
<!-- TOC depthFrom:1 depthTo:3 withLinks:1 updateOnSave:1 orderedList:0 -->
- [QCObjects](#qcobjects)
- [The meaning of the name QCObjects (Do not forget the Q)](#the-meaning-of-the-name-qcobjects-do-not-forget-the-q)
- [QCObjects Explainer Video](#qcobjects-explainer-video)
- [Table of Contents](#table-of-contents)
- [Principals](#principals)
- [Main features](#main-features)
- [Progressive Web Apps (PWA) Adopted Features](#progressive-web-apps-pwa-adopted-features)
- [Prevent Render-blocking resources](#prevent-render-blocking-resources)
- [On-Demand Resources Load](#on-demand-resources-load)
- [Lazy-loading of images in components (use lazy-src instead of src attribute in img tag)](#lazy-loading-of-images-in-components-use-lazy-src-instead-of-src-attribute-in-img-tag)
- [Cross Browser Javascript Framework for MVC Patterns](#cross-browser-javascript-framework-for-mvc-patterns)
- [Install it, make a textfield or a navigate home functionality, all in just one step.](#install-it-make-a-textfield-or-a-navigate-home-functionality-all-in-just-one-step)
- [Dynamic Components Architecture](#dynamic-components-architecture)
- [ECMA-262 Specification](#ecma-262-specification)
- [Copyright](#copyright)
- [Demo](#demo)
- [PWA Live Demo](#pwa-live-demo)
- [Demo Integrating with Foundation](#demo-integrating-with-foundation)
- [Demo Integrating with Materializecss](#demo-integrating-with-materializecss)
- [Demo Using Raw CSS](#demo-using-raw-css)
- [Example of QCObjects using and manipulating canvas objects](#example-of-qcobjects-using-and-manipulating-canvas-objects)
- [DevBlog](#devblog)
- [Fork](#fork)
- [Become a Sponsor](#become-a-sponsor)
- [Check out the QCObjects SDK](#check-out-the-qcobjects-sdk)
- [Donate](#donate)
- [Installing](#installing)
- [Using QCObjects with Atom:](#using-qcobjects-with-atom)
- [Using QCObjects in Visual Studio Code:](#using-qcobjects-in-visual-studio-code)
- [Installing with NPM:](#installing-with-npm)
- [Installing the docker playground:](#installing-the-docker-playground)
- [One-Step Installation Script for Ubuntu 18.x](#one-step-installation-script-for-ubuntu-18x)
- [One-Step Installation Script for RHEL8](#one-step-installation-script-for-rhel8)
- [One-Step Installation Script for Raspberry PI Raspbian 9](#one-step-installation-script-for-raspberry-pi-raspbian-9)
- [One-Step Installation Script for macOS](#one-step-installation-script-for-macos)
- [Install and test QCObjects on Microsoft Windows OS](#install-and-test-qcobjects-on-microsoft-windows-os)
- [QCObjects Multi-Cloud Installation](#qcobjects-multi-cloud-installation)
- [DigitalOcean One-Click Droplet](#digitalocean-one-click-droplet)
- [AWS Amazon Machine Images (AMI)](#aws-amazon-machine-images-ami)
- [Amazon Web Services AWS PIB (Private Amazon Machine Image)](#amazon-web-services-aws-pib-private-amazon-machine-image)
- [Using the development version code in the straight way into HTML5:](#using-the-development-version-code-in-the-straight-way-into-html5)
- [Using the CDN minified version code from jsDelivr CDN](#using-the-cdn-minified-version-code-from-jsdelivr-cdn)
- [Using the latest non-minified version from jsDelivr CDN](#using-the-latest-non-minified-version-from-jsdelivr-cdn)
- [Using UNPKG CDN](#using-unpkg-cdn)
- [Using CDNJS](#using-cdnjs)
- [Reference](#reference)
- [Essentials](#essentials)
- [QC\_Object](#qc_object)
- [ComplexStorageCache](#complexstoragecache)
- [Usage:](#usage)
- [Example:](#example)
- [asyncLoad](#asyncload)
- [Usage:](#usage-1)
- [Example:](#example-1)
- [Class](#class)
- [Usage:](#usage-2)
- [Example:](#example-2)
- [QC\_Append, append method](#qc_append-append-method)
- [Usage:](#usage-3)
- [Example:](#example-3)
- [The \_super\_ method](#the-_super_-method)
- [Usage:](#usage-4)
- [Example:](#example-4)
- [New](#new)
- [Usage:](#usage-5)
- [Example:](#example-5)
- [InheritClass](#inheritclass)
- [ClassFactory](#classfactory)
- [Example:](#example-6)
- [\_Crypt](#_crypt)
- [Example (1):](#example-1)
- [Example (2):](#example-2)
- [GLOBAL](#global)
- [Example:](#example-7)
- [CONFIG](#config)
- [Usage from memory:](#usage-from-memory)
- [Usage from config.json:](#usage-from-configjson)
- [Usage from an encrypted config.json:](#usage-from-an-encrypted-configjson)
- [Dynamic CONFIG Settings](#dynamic-config-settings)
- [Processor](#processor)
- [Usage:](#usage-6)
- [Example:](#example-8)
- [waitUntil](#waituntil)
- [Usage:](#usage-7)
- [Example:](#example-9)
- [Package](#package)
- [Usage:](#usage-8)
- [Example (1):](#example-1-1)
- [Example (2):](#example-2-1)
- [Import](#import)
- [Usage:](#usage-9)
- [Example (1):](#example-1-2)
- [Example (2):](#example-2-2)
- [Export](#export)
- [Usage:](#usage-10)
- [Example:](#example-10)
- [Cast](#cast)
- [Usage:](#usage-11)
- [Example:](#example-11)
- [Tag](#tag)
- [Usage:](#usage-12)
- [Example:](#example-12)
- [Ready](#ready)
- [Usage:](#usage-13)
- [Component Class](#component-class)
- [Properties](#properties)
- [Methods](#methods)
- [Component HTML Tag](#component-html-tag)
- [Available attributes](#available-attributes)
- [The name Attribute](#the-name-attribute)
- [Usage:](#usage-14)
- [Example:](#example-13)
- [The cached Attribute](#the-cached-attribute)
- [Usage:](#usage-15)
- [The data property tag declaration](#the-data-property-tag-declaration)
- [The controllerClass Attribute](#the-controllerclass-attribute)
- [Usage:](#usage-16)
- [The viewClass Attribute](#the-viewclass-attribute)
- [Usage:](#usage-17)
- [The componentClass Attribute](#the-componentclass-attribute)
- [Usage:](#usage-18)
- [The effecClass Attribute](#the-effecclass-attribute)
- [Usage:](#usage-19)
- [The template-source Attribute](#the-template-source-attribute)
- [Usage:](#usage-20)
- [The tplextension Attribute](#the-tplextension-attribute)
- [Usage:](#usage-21)
- [ComponentURI](#componenturi)
- [Example:](#example-14)
- [componentLoader](#componentloader)
- [Usage:](#usage-22)
- [Example:](#example-15)
- [buildComponents](#buildcomponents)
- [Usage:](#usage-23)
- [Example:](#example-16)
- [Controller](#controller)
- [View](#view)
- [VO](#vo)
- [Service](#service)
- [Properties](#properties-1)
- [Methods](#methods-1)
- [serviceLoader](#serviceloader)
- [Usage:](#usage-24)
- [Example:](#example-17)
- [JSONService](#jsonservice)
- [Properties](#properties-2)
- [Methods](#methods-2)
- [Example:](#example-18)
- [ConfigService](#configservice)
- [Example:](#example-19)
- [SourceJS](#sourcejs)
- [Example:](#example-20)
- [SourceCSS](#sourcecss)
- [Effect](#effect)
- [Example:](#example-21)
- [Timer](#timer)
- [Example:](#example-22)
- [List and Math Functions](#list-and-math-functions)
- [ArrayList](#arraylist)
- [ArrayCollection](#arraycollection)
- [\[ArrayList or Array\].unique](#arraylist-or-arrayunique)
- [\[ArrayList or Array\].table](#arraylist-or-arraytable)
- [\[ArrayList or Array\].sort](#arraylist-or-arraysort)
- [\[ArrayList or Array\].sortBy](#arraylist-or-arraysortby)
- [\[ArrayList or Array\].matrix](#arraylist-or-arraymatrix)
- [Usage](#usage-25)
- [\[ArrayList or Array\].matrix2d](#arraylist-or-arraymatrix2d)
- [\[ArrayList or Array\].matrix3d](#arraylist-or-arraymatrix3d)
- [range](#range)
- [Usage](#usage-26)
- [Array.sum](#arraysum)
- [Array.avg](#arrayavg)
- [Array.min](#arraymin)
- [Array.max](#arraymax)
- [SDK](#sdk)
- [SDK Components](#sdk-components)
- [org.quickcorp.components.ShadowedComponent](#orgquickcorpcomponentsshadowedcomponent)
- [Usage:](#usage-27)
- [org.quickcorp.components.FormField](#orgquickcorpcomponentsformfield)
- [Usage:](#usage-28)
- [FormField.executeBindings():](#formfieldexecutebindings)
- [Data Binding Event Change:](#data-binding-event-change)
- [Data Binding Event Blur:](#data-binding-event-blur)
- [Data Binding Event Focus:](#data-binding-event-focus)
- [Data Binding Event Keydown:](#data-binding-event-keydown)
- [org.quickcorp.components.ButtonField](#orgquickcorpcomponentsbuttonfield)
- [Usage:](#usage-29)
- [org.quickcorp.components.InputField](#orgquickcorpcomponentsinputfield)
- [Usage:](#usage-30)
- [org.quickcorp.components.TextField](#orgquickcorpcomponentstextfield)
- [Usage:](#usage-31)
- [org.quickcorp.components.EmailField](#orgquickcorpcomponentsemailfield)
- [Usage:](#usage-32)
- [org.quickcorp.components.GridComponent](#orgquickcorpcomponentsgridcomponent)
- [Usage:](#usage-33)
- [Example:](#example-23)
- [org.quickcorp.components.ModalEnclosureComponent](#orgquickcorpcomponentsmodalenclosurecomponent)
- [org.quickcorp.components.ModalComponent](#orgquickcorpcomponentsmodalcomponent)
- [org.quickcorp.components.SwaggerUIComponent](#orgquickcorpcomponentsswaggeruicomponent)
- [Usage:](#usage-34)
- [org.quickcorp.components.splashscreen.VideoSplashScreenComponent](#orgquickcorpcomponentssplashscreenvideosplashscreencomponent)
- [Example:](#example-24)
- [SDK Controllers](#sdk-controllers)
- [org.quickcorp.controllers.GridController](#orgquickcorpcontrollersgridcontroller)
- [org.quickcorp.controllers.DataGridController](#orgquickcorpcontrollersdatagridcontroller)
- [Usage:](#usage-35)
- [Example:](#example-25)
- [org.quickcorp.controllers.ModalController](#orgquickcorpcontrollersmodalcontroller)
- [org.quickcorp.controllers.FormValidations](#orgquickcorpcontrollersformvalidations)
- [Usage:](#usage-36)
- [org.quickcorp.controllers.FormController](#orgquickcorpcontrollersformcontroller)
- [\[FormController\].serviceClass](#formcontrollerserviceclass)
- [\[FormController\].formSettings](#formcontrollerformsettings)
- [\[FormController\].validations](#formcontrollervalidations)
- [Usage:](#usage-37)
- [\[FormController\].formSaveTouchHandler](#formcontrollerformsavetouchhandler)
- [A complete example of FormController](#a-complete-example-of-formcontroller)
- [org.quickcorp.controllers.SwaggerUIController](#orgquickcorpcontrollersswaggeruicontroller)
- [Usage:](#usage-38)
- [SDK Effects](#sdk-effects)
- [org.quickcorp.tools.effects.Move](#orgquickcorptoolseffectsmove)
- [Usage:](#usage-39)
- [Example:](#example-26)
- [org.quickcorp.tools.effects.MoveXInFromRight](#orgquickcorptoolseffectsmovexinfromright)
- [Usage:](#usage-40)
- [Example:](#example-27)
- [org.quickcorp.tools.effects.MoveXInFromLeft](#orgquickcorptoolseffectsmovexinfromleft)
- [Usage:](#usage-41)
- [Example:](#example-28)
- [org.quickcorp.tools.effects.MoveYInFromBottom](#orgquickcorptoolseffectsmoveyinfrombottom)
- [Usage:](#usage-42)
- [Example:](#example-29)
- [org.quickcorp.tools.effects.MoveYInFromTop](#orgquickcorptoolseffectsmoveyinfromtop)
- [Usage:](#usage-43)
- [Example:](#example-30)
- [org.quickcorp.tools.effects.RotateX](#orgquickcorptoolseffectsrotatex)
- [Usage:](#usage-44)
- [Example:](#example-31)
- [org.quickcorp.tools.effects.RotateY](#orgquickcorptoolseffectsrotatey)
- [Usage:](#usage-45)
- [Example:](#example-32)
- [org.quickcorp.tools.effects.RotateZ](#orgquickcorptoolseffectsrotatez)
- [Usage:](#usage-46)
- [Example:](#example-33)
- [org.quickcorp.tools.effects.Rotate](#orgquickcorptoolseffectsrotate)
- [Usage:](#usage-47)
- [Example:](#example-34)
- [org.quickcorp.tools.effects.Fade](#orgquickcorptoolseffectsfade)
- [Usage:](#usage-48)
- [org.quickcorp.tools.effects.Radius](#orgquickcorptoolseffectsradius)
- [Usage:](#usage-49)
- [Example:](#example-35)
- [org.quickcorp.tools.effects.Resize](#orgquickcorptoolseffectsresize)
- [Usage:](#usage-50)
- [Example:](#example-36)
- [org.quickcorp.tools.effects.WipeLeft](#orgquickcorptoolseffectswipeleft)
- [Usage:](#usage-51)
- [Example](#example-37)
- [org.quickcorp.tools.effects.WipeRight](#orgquickcorptoolseffectswiperight)
- [Usage:](#usage-52)
- [Example](#example-38)
- [org.quickcorp.tools.effects.WipeUp](#orgquickcorptoolseffectswipeup)
- [Usage:](#usage-53)
- [Example](#example-39)
- [org.quickcorp.tools.effects.WipeDown](#orgquickcorptoolseffectswipedown)
- [Usage:](#usage-54)
- [Example](#example-40)
- [SDK Misc Tools](#sdk-misc-tools)
- [org.quickcorp.tools.canvas.CanvasTool](#orgquickcorptoolscanvascanvastool)
- [org.quickcorp.tools.layouts.BasicLayout](#orgquickcorptoolslayoutsbasiclayout)
- [SDK Views](#sdk-views)
- [org.quickcorp.views.GridView](#orgquickcorpviewsgridview)
- [SDK i18n messages](#sdk-i18n-messages)
- [org.quickcorp.i18n\_messages.i18n\_messages](#orgquickcorpi18n_messagesi18n_messages)
- [Usage:](#usage-55)
- [Example](#example-41)
- [The QCObjects HTTP2 Built-In Server](#the-qcobjects-http2-built-in-server)
- [Start serving your files with QCObjects](#start-serving-your-files-with-qcobjects)
- [Principals of an N-Tier or Multitier architecture](#principals-of-an-n-tier-or-multitier-architecture)
- [Micro-services Principals](#micro-services-principals)
- [Backend settings in config.json](#backend-settings-in-configjson)
- [Backend routing](#backend-routing)
- [The QCObjects Microservice Class and Package](#the-qcobjects-microservice-class-and-package)
- [Generating a Self-Signed Certificate with QCObjects](#generating-a-self-signed-certificate-with-qcobjects)
- [Working with a Letsencrypt HTTPS certificate, Certbot and QCObjects](#working-with-a-letsencrypt-https-certificate-certbot-and-qcobjects)
- [Quick Start Guide](#quick-start-guide)
- [Quick Start your PWA (Progressive Web App)](#quick-start-your-pwa-progressive-web-app)
- [Quick Start your AMP (Accelerated Mobile Page)](#quick-start-your-amp-accelerated-mobile-page)
- [Start Coding](#start-coding)
- [Step 1: Start creating a main import file and name it like: cl.quickcorp.js. Put it into packages/js/ file directory](#step-1-start-creating-a-main-import-file-and-name-it-like-clquickcorpjs-put-it-into-packagesjs-file-directory)
- [Step 2: Then create some services inhereting classes into the file js/packages/cl.quickcorp.services.js :](#step-2-then-create-some-services-inhereting-classes-into-the-file-jspackagesclquickcorpservicesjs-)
- [Step 3: Now it's time to create the components (cl.quickcorp.components.js)](#step-3-now-its-time-to-create-the-components-clquickcorpcomponentsjs)
- [Step 4: Once you have done the above components declaration, you will now want to code your controllers (cl.quickcorp.controller.js)](#step-4-once-you-have-done-the-above-components-declaration-you-will-now-want-to-code-your-controllers-clquickcorpcontrollerjs)
- [Step 5: To use into the HTML5 code you only need to do some settings between script tags:](#step-5-to-use-into-the-html5-code-you-only-need-to-do-some-settings-between-script-tags)
- [QCObjects CLI Tool](#qcobjects-cli-tool)
- [Usage](#usage-56)
- [Options](#options)
- [Commands](#commands)
- [Use:](#use)
- [License](#license)
<!-- /TOC -->
# Principals
Here are the principals with QCObjects was made with:
0. You should type in JavaScript to code a JavaScript application.
1. Everything is an object.
2. Every object has a definition.
3. On the front-end side, any object can be stacked into the DOM or Virtual-DOM without the need to re-declare its definition.
4. Every object has a body.
5. A class should be the main definition of an object.
6. A class should be easy typed as an object itself.
7. Your code should be easily organised into packages.
8. Your code should be possible to easily scafold your applications into a clean architecture.
9. A component is an entity that has an object representation, and a tag declaration. The content of a component should be possible to be filled up remotely and locally. As a component is an object, it has a body as well, and the body of the component normally is an stacked instance of a DOM element.
10. A component can be attached to the DOM or detached from it without affecting its functionality.
11. A service call can be extended to scafold its functionality.
12. You should be able to import a package remotely.
13. You should be able to scafold your code and also controlling your savings on the server side by not doing unnecessary calls to remote sources. You should not need to repeat yourself coding this kind of controls.
14. You should be able to code your N-Tier application in a single language or syntax.
15. You should be able to apply any template you want to a component, it doesn't matter the what syntax or language the template was written with.
16. If an HTML tag is already represented by a DOM object instance, you should not need to duplicate this instance definition in order to render its contents.
17. Your HTML main page should be clean. But you should be able to bind what controls the tag behaviour without affecting the HTML syntax.
18. The order of execution of your code should be easily understandable and readable from the code, and the rendering process of every component should have and execution control in as many layers you need.
19. A layered pattern (like MVC or MVCC) should be present for every component. It doesn't matter if you define every layer or not.
20. The behaviour of a component should not be determined by its rendering process.
21. It is necessary a components stack that splits the DOM into a subjacent tree of attached elements. So now it exists and it is called The QCObjects Nested Components Stack.
22. You should be able to extend a component instance. But you should be able to control its dynamic behaviour without affecting its initial declaration.
23. You should be able to apply simultaneous visual effects and animations in an easy way to any DOM element instance.
24. You should be able to control the visual effects and animations either from CSS or JavaScript without affecting the performance.
25. You should be able to control the behaviour of your code Into-the-box and out-of-the-box and survive doing it.
# Main features
- Built-In & custom templates for Progressive Web Apps (PWA) and Accelerated Mobile Pages (AMP)
- Revolutionary UI Effects
- Breakthrough backend micro-services
- The simplicity of a wonderful layout design
- Fully usable CLI tools
- Objects & Components driven architecture
- Front-end and back-end together in a full-stack environment
- Recursive routing for components
- Built-In nested components management
- Fully integrated MVC pattern (Model, View, Controller)
- Dynamic Data Objects
- Based on N-Tier Architecture concepts
# Progressive Web Apps (PWA) Adopted Features
## Prevent Render-blocking resources
To prevent Render-blocking resources, QCObjects has implemented the [Package](#Package) factory function.
## On-Demand Resources Load
With a dynamic components driven architecture, QCObjects is rendering every visual resource that is inside of a component only when the component is building itself, and every component is connected to a tree called global.componentsStack that is actually pointing to every component instance and its subcomponents. Every time a component is rebuilt, visual resources are dynamically reloaded on-demand in the most efficient way, so you can forget all the nasty code that you were needing to controll the resource loading process with other frameworks.
## Lazy-loading of images in components (use lazy-src instead of src attribute in img tag)
Since the version 2.1.251, QCObjects provide an easy way to lazy load the images, using the latest standard for browsers.
```html
<img src="img/preloader.svg" lazy-src="img/myrealimage.png"/>
```
In the above code, a preloader (light-weight) image is used to be loaded in the first instance, and a **lazy-src** attribute is used to set the real image to show after lazy loading process. QCObjects will load all the **<img>** declared tags inside a component in lazy mode if they have a lazy-src attribute, after the component is rebuilt or loaded. Also, QCObjects will use the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) (when available) to determine whether the lazy-src or src image is visually useful to be showed.
The effect of lazy loading is only high visible on the first time the PWA is loaded. The next time, the speed of loading will be significantly increased making more difficult to the human eye to see the result. However this feature makes a lot of difference in terms of user experience when the internet connection has low speed issues or the images are extremely large. This feature is a part of the recommended features for PWAs writen by [Mozzila Developers Network](https://developer.mozilla.org/) in an article about Progressive loading. You can read that article [here](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Loading)
If you don't want to use lazy loading for images, you can always keep the normal way of loading by not adding the **lazy-src** attribute to the **<img>** tag and using the traditional **src**.
# Cross Browser Javascript Framework for MVC Patterns
----------------------------------------
[QCObjects](https://qcobjects.dev) is a javascript framework designed to make easier everything about the MVC patterns implementation into the pure javascript scope. You don't need to use typescript nor any transpiler to run [QCObjects](https://qcobjects.dev). It runs directly on the browser and it uses pure javascript with no extra dependencies of code. You can make your own components expressed in real native javascript objects or extend a native DOM object to use in your own way. You can also use [QCObjects](https://qcobjects.dev) in conjunction with CSS3 frameworks like [Foundation] (https://foundation.zurb.com), [Bootstrap] (https://getbootstrap.com) and mobile javascript frameworks like [PhoneGap] (https://phonegap.com) and OnsenUI (https://onsen.io)

# Install it, make a textfield or a navigate home functionality, all in just one step.
QCObjects in installable in your computer, it comes with a CLI Tool and commands to create your application template in one step. Navigate home without leaving the webpage and make a shadowed textfield in one step.
# Dynamic Components Architecture

[](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects?ref=badge_shield)
# ECMA-262 Specification
--------------------------
See
[ECMAScript® 2020 Language Specification](https://tc39.github.io/ecma262/#sec-intro) for reference
# Copyright
-----------
Copyright (c) Jean Machuca and [QuickCorp](https://quickcorp.org) <info@quickcorp.cl>
# Demo
--------------
## PWA Live Demo
Check out a live demo of pure QCObjects based frontend Progressive Web App here:
[PWA QCObjects](https://newapp.qcobjects.dev/)
## Demo Integrating with Foundation
Check out a demo using Foundation components here:
[Demo Using Foundation](https://github.com/QuickCorp/quickobjects_sample1foundation)
## Demo Integrating with Materializecss
Check out a demo using MaterializeCSS here:
[Demo Using Materializecss](https://qln.link)
## Demo Using Raw CSS
Check out a demo using raw CSS:
[Demo Using Raw CSS](https://github.com/QuickCorp/qcobjects_profile_browser)
## Example of QCObjects using and manipulating canvas objects
The following code shows how QCObjects can manipulate canvas objects directly and inside components
```html
<script type="module">
import "https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.4.55/QCObjects.js";
/**
* Declare a Component containing a canvas element and then add it to document body
*/
class CanvasComponent extends Component {
tplsource= "none";
constructor ({name, body, width, height}){
body = _DOMCreateElement("canvas");
body.width = width;
body.height = height;
super({name,body});
}
}
let mycanvas = new CanvasComponent(
{
name:"mycanvas",
width: 400,
height: 400
});
document.body.append(mycanvas);
</script>
```
# DevBlog
--------------
The [Official DevBlog of QCObjects](https://devblog.qcobjects.org/) is hosted on [Hashnode](https://hashnode.com/). The DevBlog is personally written by Jean Machuca, the author of [QCObjects](https://qcobjects.com) and and he is explaining in detail how are the best practices and giving the best tips and tricks to use the most advanced features of QCObjects.
# Fork
--------------
Please fork this project or make a link to this project into your README.md file. Read the LICENSE.txt file before you use this code.
# Become a Sponsor
------------------
If you want to become a sponsor for this wonderful project you can do it [here](https://sponsorsignup.qcobjects.dev/)
# Check out the QCObjects SDK
----------------------------
You can check out the [QCObjects SDK](https://sdk.qcobjects.dev/) and follow the examples to make your own featured components
# Donate
--------------
If you like this code please [DONATE](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)!
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)
[](https://www.patreon.com/join/qcobjects?)
# Installing
------------
## Using QCObjects with Atom:
```shell
> apm install qcobjects-syntax
```
https://atom.io/packages/qcobjects-syntax
## Using QCObjects in Visual Studio Code:
[](https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode)
https://marketplace.visualstudio.com/items?itemName=Quickcorp.QCObjects-vscode
## Installing with NPM:
```shell
> npm install qcobjects-cli -g && npm install qcobjects --save
```

## Installing the docker playground:
```shell
docker pull -a quickcorp/qcobjects-playground && docker run -it --name qcobjects-playground --rm -it quickcorp/qcobjects-playground
```

## One-Step Installation Script for Ubuntu 18.x
WARNING: Do this only in a fresh|blank|brandnew installation of Ubuntu 18.x, don't do it into an existing production environment. You will be asked for sudo grant permission.
```shell
curl -L https://cdn.qcobjects.dev/install_qcobjects_ubuntu18x.sh |sh
```
WARNING: I'm not responsible for damaging your infrastructure by using an automated installation script into an unsafe network. Make sure all your repos and scripts are under HTTPS with a valid certificate. For better safe results I recommended you to download the script, edit it for your special needs and then execute it in your machine as local.
## One-Step Installation Script for RHEL8
```shell
curl -L https://cdn.qcobjects.dev/install_qcobjects_rhel8.sh |sh
```
## One-Step Installation Script for Raspberry PI Raspbian 9
```shell
su -c "curl -L https://cdn.qcobjects.dev/install_qcobjects_raspbian9.sh |sh" root
```
## One-Step Installation Script for macOS
Tested on macOS Catalina 10.15.3
```shell
curl -L https://cdn.qcobjects.dev/install_qcobjects_macOS.sh | zsh
```
## Install and test QCObjects on Microsoft Windows OS
1.- Install the latest version of NodeJS for Windows from [here](https://nodejs.org/)
2.- From cmd install qcobjects-cli using npm
```powershell
npm i qcobjects-cli -g
```
3.- Create a directory for your project
```powershell
md mynewproject && cd mynewproject
```
4.- Create a new QCObjects Progressive Web Application
```powershell
qcobjects create mynewproject --pwa
```

## QCObjects Multi-Cloud Installation
QCObjects is natively supported by the most famous cloud providers. In most of them, you can install it and set everything up and running in just one step.
### DigitalOcean One-Click Droplet
If you want to forget apt-get and the config guide. Go straight to deploying your project using a preconfigured 1-Click App including QCObjects CLI, QCObjects-SDK and QCObjects HTTP2 Built-In Server, then spin it up on a Droplet VM or a Kubernetes cluster in 60 seconds or less.
[Create Your Own QCObjects DigitalOcean Droplet here](https://marketplace.digitalocean.com/apps/qcobjects)
### AWS Amazon Machine Images (AMI)
An Amazon Machine Image (AMI) provides the information required to launch an instance. You must specify an AMI when you launch an instance. You can launch multiple instances from a single AMI when you need multiple instances with the same configuration. You can use different AMIs to launch instances when you need instances with different configurations.
An AMI includes the following:
- One or more EBS snapshots, or, for instance-store-backed AMIs, a template for the root volume of the instance (for example, an operating system, an application server, and applications).
- Launch permissions that control which AWS accounts can use the AMI to launch instances.
- A block device mapping that specifies the volumes to attach to the instance when it's launched.
[Start building your QCObjects AMI here](https://aws.amazon.com/marketplace/pp/B07YZRH7VB)
### Amazon Web Services AWS PIB (Private Amazon Machine Image)
A Private Image lets you build a new AMI by installing AWS Marketplace software on an image you choose from the AMIs available to your AWS account, this allows you to better meet internal specifications for security, management and compliance. As with standard AWS Marketplace AMIs, each Private Image will comprise a subscription for the installed product and have software usage billed via AWS Marketplace.
[Start building your QCObjects Amazon Private Image here](https://aws.amazon.com/marketplace/pp/B07YZRH7VB)
## Using the development version code in the straight way into HTML5:
```html
<script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>
```
## Using the CDN minified version code from jsDelivr CDN
```html
<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.min.js"></script>
```
## Using the latest non-minified version from jsDelivr CDN
```html
<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.js"></script>
```
## Using UNPKG CDN
```html
<script src="https://unpkg.com/qcobjects@latest/QCObjects.js"></script>
```
## Using CDNJS
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/[VERSION]/QCObjects.js"></script>
```
Where [VERSION] is the corresponding latest version using numeric notation, example: to use version 2.1.420:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.js"></script>
```
You don't need to minify QCObjects, but if you still want to use the minified code, you can do this:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.min.js"></script>
```
Again, Change 2.1.420 to the number of the version that you want to use.
# Reference
------------
## Essentials
Here are the essentials symbols and concepts of [QCObjects](https://qcobjects.dev) Reference
### QC_Object
Basic Type of all elements
### ComplexStorageCache
With **ComplexStorageCache** you can handle a cache for any object and save it in the local storage.
#### Usage:
```javascript
var cache = new ComplexStorageCache({
index:object.id, // Object Index
load:(cacheController)=>{}, // A function to execute for the first time
alternate: (cacheController)=>{} // The alternate function to execute from the second time the source coude is loaded
});
```
#### Example:
```javascript
var dataObject = {id:1,
prop1:1,
prop2:2
};
var cache = new ComplexStorageCache({
index: dataObject.id,
load: (cacheController) => {
dataObject = {
id:dataObject.id,
prop1:dataObject.prop1*2, // changing a property value
prop2:dataObject.prop2
};
return dataObject;
},
alternate: (cacheController) => {
dataObject = cacheController.cache.getCached(dataObject.id); // setting dataObject with the cached value
return;
}
});
// Next time you can get the object from the cache
var dataObjectCopyFromCache = cache.getCached(dataObject.id);
console.log(dataObjectCopyFromCache); // will show the very same object value than dataObject
```
### asyncLoad
The **asyncLoad** function loads a code once in async mode. This is useful to asure some initial process don't replicate its execution and aren't loaded after sensitive code.
#### Usage:
```javascript
asyncLoad(()=>{
// my code here
},args);
// Where args is an array of arguments, it can be the "arguments" special object
```
#### Example:
```javascript
let doSomething = (arg1,arg2)=>{
asyncLoad((arg1,arg2)=>{
console.log(arg1);
console.log(arg2);
},arguments);
};
doSomething(1,2); // the code of doSomething will be executed once after the rest of asyncLoad queue of functions and before the execution of Ready event.
```
### Class
This is NOT the class definition of ECMAScript 2015 (see [class ECMAScript 2015](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) for reference).
Class is a special function to help you to declare a class in an easier and compatible way. It works cross-browser, and I hope ECMA could adopt something like that in the future. To let javascript not to be confuse about this, [QCObjects](https://qcobjects.dev) uses "Class" not "class" (note the Camel Case).
#### Usage:
```javascript
Class('MyClassName',MyClassDefinition);
```
Where **MyClassDefinition** is an object with a QCObjects **prototype**
#### Example:
```javascript
Class('MyClassName',InheritClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod1: function (){
// some code here
// note you can use "this" object
return this.propertyName1;
},
classMethod2: function () {
// some code here
return this.propertyName2;
}
});
var newObject = New(MyClassName,{
propertyName1:1, // this initializes the value in 1
propertyName2:"some value"
});
console.log(newObject.classMethod1()); // this will show number 1
console.log(newObject.classMethod2()); // this will show "some value"
```
### QC_Append, append method
This is a special method inserted to make your life easier when you want to dynamically manipulate the **DOM**. You can insert even a **Component**, a **QCObjects** Object or a **DOM** Element inside another **HTMLElement**.
##### Usage:
```javascript
[element].append([object or element]);
```
#### Example:
```javascript
// This will create a QCObjects class named "canvas" extending a HTMLCanvasElement with a customAttr property that has a "custom" value
Class('canvas',HTMLCanvasElement,{
customAttr:'custom'
});
// This will declare an instance canvas1 from the class canvas
let canvas1 = New(canvas,{
width:100,
height:100,
});
// This will append the canvas1 object to the document body
document.body.append(canvas1);
```
### The \_super\_ method
When you extend a QCObjects class from another one, you can use \_super\_ method to get an instance from the main class definition.
#### Usage:
```javascript
_super_('MySuperClass','MySuperMethod').call(this,params)
// where this is the current instance and params are method parameters
```
#### Example:
```javascript
Class('MySuperiorClass',InheritClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod1: function (){
// some code here
// note you can use "this" object
return this.propertyName1;
},
});
Class('MyClassName',MySuperiorClass,{
propertyName1:0, // just to declare purpose
propertyName2:'',
classMethod2: function () {
// The next line will execute classMethod1 from MySuperiorClass
// but using the current instance of MyClassName1
return _super_('MySuperiorClass','classMethod1').call(this);
}
});
var newObject = New(MyClassName,{
propertyName1:1, // this initializes the value in 1
propertyName2:"some value"
});
console.log(newObject.classMethod2()); // this will show the number 1
```
### New
Creates an object instance of a QCObjects class definition.
#### Usage:
```javascript
let objectInstance = New(QCObjectsClassName, properties);
// where properties is a single object with the property values
```
NOTE: In the properties object you can use single values or getter as well but they will be executed once.
#### Example:
```javascript
Class('MyCustomClass',Object);
let objectInstance = New(MyCustomClass,{
prop1:1,
get randomNumber(){ // this getter will be executed once
return Math.random();
}
});
console.log(objectInstance.randomNumber); // it will show console.log(objectInstance.prop1); // it will show number 1
```
### InheritClass
A single common used QCObjects class definition.
### ClassFactory
Use **ClassFactory** to get the Class declaration factory instance of a QCObjects Class
You can get either a Class factory from a Package or from the Class queue stack
To retreive the ClassFactory from the Class queue stack you can simply use the name of a Class as calling directly in the code.
#### Example:
```javascript
/* When you declare MyClass using Class() it is instantly added to the Class queue stack
* and you can get the factory either using ClassFactory() or calling the name MyClass straight in the code
*/
Class('MyClass',{
a:1
})
console.log(MyClass == ClassFactory('MyClass')) // it will show true
```
```javascript
/* On the other hand, ClassFactory() will be so useful when you define a Class into a Package
*/
Package('org.quickcorp.package1',[
Class('MyClass',{
a:1
})
])
console.log(MyClass == ClassFactory('MyClass')) // it will still show true
// The following line will show true as well
console.log(MyClass == ClassFactory('org.quickcorp.package1.MyClass'))
```
```javascript
/* The interesting thing is when you have declared more than one Class using the
* same name MyClass into different packages but with different property default values
* and even properties
*/
Package('org.quickcorp.package1',[
Class('MyClass',{
a:1
})
])
Package('org.quickcorp.package2',[
Class('MyClass',{
a:2,
b:1
})
])
// The last declaration of MyClass will be the one survival in the Class queue
// so the reference MyClass in the code will point to that one
console.log(MyClass == ClassFactory('MyClass')) // it will still show true
// In this case as the MyClass defined in the org.quickcorp.package1 will not be the same
// as the one in the org.quickcorp.package2, but the MyClass in the package2 is the last one
// The following line will show false
console.log(MyClass == ClassFactory('org.quickcorp.package1.MyClass'))
// The following line will show true
console.log(MyClass == ClassFactory('org.quickcorp.package2.MyClass'))
// The following line will show false
console.log(ClassFactory('org.quickcorp.package1.MyClass') == ClassFactory('org.quickcorp.package2.MyClass'))
```
The above examples are intentionally done to explain and show how the scope of the Class definitions in QCObjects is protected and handled and it is reflected in the use of ClassFactory.
So you are gonna want to use ClassFactory when you need complete control over the scope when extending Classes
**Example**
```javascript
// When normally you extend a Class using the Class queue you do:
Class('MyExtendedClass',MyInheritClass,{
extendedProp1: 'value of prop',
extendedProp2: 2
})
```
```javascript
/* But to protect the scope from misleading by reference, you can asure that MyInheritClass
is the one you want to extend by declaring it into a package and then extend it
*/
Package('org.quickcorp.mypackage1',[
Class('MyInheritClass',{
sourceProp:1
}),
])
// The following code is a definition of MyExtendedClass into a different package
// org.quickcorp.package2
// extending MyInheritClass using ClassFactory to retreive the Class from the source package
// org.quickcorp.mypackage1
Package('org.quickcorp.mypackage2',[
Class('MyExtendedClass',ClassFactory('org.quickcorp.mypackage1.MyInheritClass'),{
extendedProp1: 'value of prop',
extendedProp2: 2
})
])
// this will show the number 1 (as the inherited default value of sourceProp)
console.log(New(MyExtendedClass).sourceProp)
```
### \_Crypt
With \_Crypt you can encode serializable objects by a passphrase
#### Example (1):
```javascript
var _string = New(_Crypt,{string:'hello world',key:'some encryption md5 key'});
console.log(_string._encrypt());
console.log(_string._decrypt()); // decodes encrypted string to the source
```
#### Example (2):
```javascript
_Crypt.encrypt('hola mundo','12345678866');
_Crypt.decrypt('nqCelFSiq6Wcpw==','12345678866');
```
### GLOBAL
**GLOBAL** is a special QCObjects class to reach the global scope. It has a set and a get method to help you to manage the internal GLOBAL properties.
#### Example:
```javascript
GLOBAL.set('globalProperty1','some value in global scope');
var globalProperty1 = GLOBAL.get('globalProperty1');
```
### CONFIG
CONFIG is a smart class that manages the global settings of your application. You can get the properties either from a config.json or from the memory previously saved by a set() call.
#### Usage from memory:
1.- In your initial code set the CONFIG initial values:
```javascript
CONFIG.set('someSettingProperty','some initial value');
```
2.- Then you can access it from anywhere in your code by using the get method:
```javascript
var someSettingProperty = CONFIG.get('someSettingProperty');
```
#### Usage from config.json:
1.- You need to indicate first that you are using a config.json file by setting the "useConfigService" value to true
```javascript
CONFIG.set('useConfigService',true); // using config.json for custom settings config
```
2.- Once you have set the value above QCObjects will know and look to the next CONFIG settings into the file config.json in the basePath folder of your application.
#### Usage from an encrypted config.json:
There is also a way to use an encrypted config.json file in order to protect your settings robots that can steal unprotected data from your web application (like API keys web crawlers).
To encrypt your json file go to https://config.qcobjects.dev, put your domain and the config.json content. The tool will encrypt your json and you can copy the encrypted content to insert it in your config.json file. QCObjects will know the data is encrypted and the process to decode the data will be transparent for you.
#### Dynamic CONFIG Settings
Sometimes you will need to set a value from a source that isn't static, like the ENV vars or another custom source of dynamic data. To get a value using CONFIG from a dynamic source you have to use a processor. There are common processors predefined like $ENV (only available on CLI, Collab and Node) and $config (available on all environments).
Processors are called as a meta value either into the config.json file or in the CONFIG Class.
```json
// file: config.json
{
"domain":"localhost",
"env1":"$ENV(ENV1)",
"customSettings":{
"value1":"$config(domain)"
}
}
```
```javascript
let value1 = CONFIG.get("customSettings").value1;
// value1 = "localhost";
let env1 = CONFIG.get("env1");
//env1 = (environment variable ENV1)
```
```javascript
// sets the key "api_key" of the CONFIG settings to a dynamic processor $ENV that recovers the value of API_KEY from the environment variables
CONFIG.set("api_key","$ENV(API_KEY)");
let api_key = CONFIG.get("api_key");
// api_key will contain the value of the system API_KEY environment var
// ($ENV processor returns a valid value only on Node.js , QCObjects CLI and QCObjects Collab engine)
```
### Processor
Static Class that used to set custom processors for CONFIG.
#### Usage:
```javascript
Processor.setProcessor(processor)
```
Where **processor** is a named function that receives the arguments of the processor
#### Example:
You have an environment variable called **SERVICE_URL** that stores a url of a service. You have to use that value in your config settings in the **serviceURL** value but you also need to set the **host** and the **port** settings using the parsed value of that url. To parse the value of SERVICE_URL environment variable on-demand and fill up the corresponding settings in your config.json, Your config.json file will look like this:
```json
// file: config.json
{
"serviceURL":"$ENV(SERVICE_URL)",
"host":"$SERVICE_HOST(SERVICE_URL)",
"port":"$SERVICE_PORT(SERVICE_URL)"
}
```
The **$SERVICE_HOST** and **$SERVICE_PORT** processors don't exist. To define them, you must use:
```javascript
// execute the next code in your init.js file or before to load the CONFIG settings
let SERVICE_HOST = function (arg){
var processorHandler = this; // to make this always works, do not use arrow functions to define your
let serviceURL = new URL(processorHandler.processors.ENV(arg));
return serviceURL.h