diff --git a/.gitignore b/.gitignore index a2f90fa..b94ed25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /Data /Public/data *[Ss]ecrets* -/Go/Modules \ No newline at end of file +/Go/Modules +/Bin/AnP.golang.debug \ No newline at end of file diff --git a/Bin/AnP.0.0.3.go.linux.386 b/Bin/AnP.0.0.3.go.linux.386 index 409e53a..d935641 100755 Binary files a/Bin/AnP.0.0.3.go.linux.386 and b/Bin/AnP.0.0.3.go.linux.386 differ diff --git a/Bin/AnP.0.0.3.go.linux.amd64 b/Bin/AnP.0.0.3.go.linux.amd64 index d673c04..92ebbd8 100755 Binary files a/Bin/AnP.0.0.3.go.linux.amd64 and b/Bin/AnP.0.0.3.go.linux.amd64 differ diff --git a/Bin/AnP.0.0.3.go.linux.arm32 b/Bin/AnP.0.0.3.go.linux.arm32 index 9b11839..de1be4a 100755 Binary files a/Bin/AnP.0.0.3.go.linux.arm32 and b/Bin/AnP.0.0.3.go.linux.arm32 differ diff --git a/Bin/AnP.0.0.3.go.linux.arm64 b/Bin/AnP.0.0.3.go.linux.arm64 index 97cd6f2..42d6f95 100755 Binary files a/Bin/AnP.0.0.3.go.linux.arm64 and b/Bin/AnP.0.0.3.go.linux.arm64 differ diff --git a/Bin/AnP.0.0.3.go.windows.386.exe b/Bin/AnP.0.0.3.go.windows.386.exe index 0cdc782..a277a34 100755 Binary files a/Bin/AnP.0.0.3.go.windows.386.exe and b/Bin/AnP.0.0.3.go.windows.386.exe differ diff --git a/Bin/AnP.0.0.3.go.windows.amd64.exe b/Bin/AnP.0.0.3.go.windows.amd64.exe index 304cce8..c6b97d9 100755 Binary files a/Bin/AnP.0.0.3.go.windows.amd64.exe and b/Bin/AnP.0.0.3.go.windows.amd64.exe differ diff --git a/Bin/AnP.0.0.3.go.windows.arm32.exe b/Bin/AnP.0.0.3.go.windows.arm32.exe index 5d0a388..a4b2d53 100755 Binary files a/Bin/AnP.0.0.3.go.windows.arm32.exe and b/Bin/AnP.0.0.3.go.windows.arm32.exe differ diff --git a/Bin/AnP.golang.debug b/Bin/AnP.golang.debug index d673c04..92ebbd8 100755 Binary files a/Bin/AnP.golang.debug and b/Bin/AnP.golang.debug differ diff --git a/Go/Drivers/HTTPDriver.go b/Go/Drivers/HTTPDriver.go index e7ef570..1c0148c 100644 --- a/Go/Drivers/HTTPDriver.go +++ b/Go/Drivers/HTTPDriver.go @@ -38,6 +38,8 @@ func NewHTTPDriver(anp Models.AnPModel, inputs any) *HTTPDriver { }, inputs, Utils.GetPointer[any](true)), Utils.GetPointer(true)), } + Models.DebugPrint(server.host + ":" + strconv.FormatInt(int64(server.port), 10)) + Models.DebugPrint(server.host, ":", server.port) if server.listener == nil { diff --git a/Go/Managers/RoutesManager.go b/Go/Managers/RoutesManager.go index 9d616ca..547d6c3 100644 --- a/Go/Managers/RoutesManager.go +++ b/Go/Managers/RoutesManager.go @@ -155,6 +155,8 @@ func (_self RoutesManager) Go(request_interface Interfaces.RequestModelInterface var done bool = false var request Models.RequestModel = request_interface.(Models.RequestModel) + Models.DebugPrint([]any{_self.domains, request.Domain}) + if slices.Contains(_self.domains, request.Domain) || slices.Contains(_self.domains, "") { var code int = 404 diff --git a/Go/Models/RequestModel.go b/Go/Models/RequestModel.go index 4b763eb..20e1a0a 100644 --- a/Go/Models/RequestModel.go +++ b/Go/Models/RequestModel.go @@ -3,6 +3,7 @@ package Models import ( "AnP/Utils" "net/http" + "strconv" "strings" ) @@ -10,13 +11,31 @@ type RequestModel struct { Domain string Method string URL string + Port int } func NewRequestModel(request *http.Request) RequestModel { + DebugPrint(strings.ToLower(request.Method) + ":" + request.Host + request.RequestURI) + + var host []string = strings.Split(request.Host, ":") + var port int64 = 80 + + if len(host) > 1 { + + var error error + + port, error = strconv.ParseInt(host[1], 10, 32) + if error != nil { + port = 80 + } + + } + return RequestModel{ - Domain: request.Host, + Domain: host[0], Method: strings.ToLower(request.Method), URL: request.RequestURI, + Port: int(port), } } @@ -25,6 +44,7 @@ func (_self RequestModel) ToJSON(header string) string { header + "domain": _self.Domain, header + "method": _self.Method, header + "url": _self.URL, + header + "port": _self.Port, }) } @@ -33,5 +53,6 @@ func (_self RequestModel) ToJSONItem(header string) map[string]string { header + "domain": _self.Domain, header + "method": _self.Method, header + "url": _self.URL, + header + "port": strconv.FormatInt(int64(_self.Port), 10), } } diff --git a/HTML/AnP.wmarkdown.html b/HTML/AnP.wmarkdown.html index de107c6..c511c02 100644 --- a/HTML/AnP.wmarkdown.html +++ b/HTML/AnP.wmarkdown.html @@ -29,7 +29,7 @@ import {AnPLoader} from "/ecma/AnPLoader.ecma.js"; import {AnP} from "/ecma/Application/AnP.ecma.js"; import {Utils} from "/ecma/Utils/Utils.ecma.js"; - import {WMarkDown} from "https://wmarkdown.local/ecma/WMarkDown.ecma.js"; + import {WMarkDown} from "https://wmarkdown.gocal/ecma/WMarkDown.ecma.js"; new AnPLoader({ scripts : [[ @@ -38,8 +38,8 @@ ]], styles : [[ "/css/FontAwesome-6.7.2.css", - "https://wmarkdown.local/css/WMarkDown.icons.FontAwesome.css", - "https://wmarkdown.local/scss/WMarkDown.scss", + "https://wmarkdown.gocal/css/WMarkDown.icons.FontAwesome.css", + "https://wmarkdown.gocal/scss/WMarkDown.scss", "/scss/AnP.scss" ]] }, () => { diff --git a/Public/ecma/Application/AnP.ecma.js b/Public/ecma/Application/AnP.ecma.js index f9d4575..58ce29b 100644 --- a/Public/ecma/Application/AnP.ecma.js +++ b/Public/ecma/Application/AnP.ecma.js @@ -9,6 +9,7 @@ import {Components} from "./Components.ecma.js"; import {Check} from "../Utils/Check.ecma.js"; import {Utils} from "../Utils/Utils.ecma.js"; import {Patterns} from "../Utils/Patterns.ecma.js"; +import {EventsManager} from "../Managers/EventsManager.ecma.js"; /** * @callback anp_preload_callback @@ -79,6 +80,12 @@ export const AnP = (function(){ /** @type {number} */ chain_length = 11; + /** @type {EventsManager} */ + this.on_ready = new EventsManager({ + autoexecute : false, + times : 1 + }); + /** @type {SettingsManager} */ this.settings = null; /** @type {I18NManager} */ @@ -133,16 +140,19 @@ export const AnP = (function(){ set_basics(); - self.settings.get("autostart") && self.start(); + if(self.settings.get("autostart")) + self.start(self.on_ready.execute); + else + self.on_ready.execute(); - } + }; /** * @returns {void} * @access private */ const constructor = () => { - if(Utils.get_value("debug_mode")){ + if(Utils.get_value("debug_mode", inputs)){ try{ execute_constructor(); }catch(exception){ diff --git a/Public/ecma/Application/Attributes.ecma.js b/Public/ecma/Application/Attributes.ecma.js index 52c0a4e..6c404c5 100644 --- a/Public/ecma/Application/Attributes.ecma.js +++ b/Public/ecma/Application/Attributes.ecma.js @@ -49,13 +49,13 @@ export const Attributes = (function(){ const self = this, /** @type {Array.} */ without_values = [ - "disabled", "readonly" + "disabled", "readonly", "checked", "selected" ], /** @type {Array.} */ normals = [ "src", "class", "title", "id", "alt", "target", "href", "style", "lang", "type", "name", "placeholder", "min", "max", "value", "step", "disabled", - "readonly" + "readonly", "for", "checked", "selected", "method", "action" ]; /** @type {boolean} */ let started = false; @@ -202,6 +202,36 @@ export const Attributes = (function(){ }); }); }; + + /** + * @param {!(Object.|Array.)} attributes + * @param {?(string|Array.)} [for_remove = null] + * @returns {Object.} + * @access public + */ + this.get_for_input = (attributes, for_remove = null) => { + + /** @type {string|null} */ + let text = Utils.get_value(["text", "title", "placeholder"], attributes = Utils.get_dictionary(attributes)); + /** @type {string|null} */ + const i18n = Utils.get_value(["i18n", "name"], attributes); + + if(i18n){ + text = anp.i18n.get([text, i18n]); + attributes.i18n = i18n; + attributes.i18n_without || (attributes.i18n_without = true); + }; + if(!Check.is_null_or_undefined(text)){ + attributes.placeholder = text + "..."; + attributes.title = text; + }; + + Attributes.remove(attributes, ["text"].concat( + for_remove ? Check.is_array(for_remove) ? for_remove : [for_remove] : [] + )); + + return attributes; + }; constructor(); @@ -256,5 +286,17 @@ export const Attributes = (function(){ return item; }; + /** + * @param {!(string|Array.)} i18n + * @param {!string} suffix + * @returns {string|Array.|null} + * @access public + * @static + */ + Attributes.i18n_add_suffix = (i18n, suffix) => ( + Check.is_string(i18n) ? i18n + "_" + suffix : + Check.is_array(i18n) ? Utils.get_keys(i18n).map(key => key + "_" + suffix) : + null); + return Attributes; })(); \ No newline at end of file diff --git a/Public/ecma/Application/Components.ecma.js b/Public/ecma/Application/Components.ecma.js index 62c7500..a13bed2 100644 --- a/Public/ecma/Application/Components.ecma.js +++ b/Public/ecma/Application/Components.ecma.js @@ -121,58 +121,104 @@ export const Components = (function(){ const set_childs = childs => Check.is_string(childs[0]) ? [childs] : childs; /** - * @param {...Array.|Array.|null>, Array.>|null} items + * @param {...([string, Object.|Array.|null>, Array.]|null)} items * @returns {string} * @access public */ - this.set = (...items) => items.reduce((html, [tag, attributes, childs]) => { + this.set = (...items) => items.reduce((html, data) => { - const subitem = ( - self[tag] && (!attributes || !attributes.built) ? self[tag](...Utils.get_array(attributes)) : - `<` + tag + anp.attributes.create(attributes, null, "built") + `>` + ( - Check.is_array(childs) && childs.length ? self.set(...set_childs(childs)) : - Check.is_null_or_undefined(childs) ? "" : - "" + childs) + ``); + /** @type {string} */ + let subitem = ``; + + if(data){ + + /** @type {[string, Object.|Array.|null>, Array.]} */ + const [tag, attributes, childs] = data; + + subitem = ( + self[tag] && (!attributes || !attributes.built) ? self[tag](...Utils.get_array(attributes)) : + `<` + tag + anp.attributes.create(attributes, null, "built") + `>` + ( + Check.is_array(childs) && childs.length ? self.set(...set_childs(childs)) : + Check.is_null_or_undefined(childs) ? "" : + "" + childs) + ``); + + }; return html + (Check.is_array(subitem) ? self.set(...[subitem]) : subitem); }, ``); + /** + * @param {!HTMLElement} item + * @param {...Array.|Array.|null>, Array.>|null>} items + * @returns {void} + * @access public + */ + this.set_direct_to = (item, ...items) => { + items.forEach(([tag, attributes, childs]) => { + if(self[tag] && (!attributes || !attributes.built)){ + + /** @type {string|Array.|HTMLElement|NodeList} */ + const subitem = self[tag](...Utils.get_array(attributes)); + + if(Check.is_string(subitem)) + item.innerHTML += subitem; + else if(Check.is_array(subitem)) + self.set_direct_to(item, subitem); + else if(Check.is_html_items(subitem)) + subitem.forEach(subnode => item.appendChild(subnode)); + else if(Check.is_html_item(subitem)) + item.appendChild(subitem); + + }else{ + + /** @type {HTMLElement} */ + const subitem = item.appendChild(document.createElement(tag)); + + anp.attributes.set(subitem, attributes, null, ["built"]); + if(!Check.is_null_or_undefined(childs)){ + if(Check.is_array(childs)) + childs.length && self.set_direct_to(subitem, ...set_childs(childs)); + else + subitem.innerHTML = childs; + }; + + }; + }); + }; + /** * @param {!(string|HTMLElement)} item * @param {...Array.|Array.|null>, Array.>|null>} items - * @returns {string} + * @returns {void} * @access public */ this.set_to = (item, ...items) => { anp.preload(item, (item, asynchronous, ok) => { - ok && items.forEach(([tag, attributes, childs]) => { - if(self[tag] && (!attributes || !attributes.built)){ - - /** @type {string|Array.|HTMLElement|NodeList} */ - const subitem = self[tag](...Utils.get_array(attributes)); - - if(Check.is_string(subitem)) - item.innerHTML += subitem; - else if(Check.is_array(subitem)) - self.set_to(item, subitem); - else if(Check.is_html_items(subitem)) - subitem.forEach(subnode => item.appendChild(subnode)); - else if(Check.is_html_item(subitem)) - item.appendChild(subitem); - - }else{ - - /** @type {HTMLElement} */ - const subitem = item.appendChild(document.createElement(tag)); - - anp.attributes.set(subitem, attributes, null, ["built"]); - Check.is_array(childs) && childs.length && self.set_to(subitem, ...set_childs(childs)); - - }; - }); + ok && self.set_direct_to(item, ...items); }); }; + /** + * @param {!(string|HTMLElement)} item + * @param {...Array.|Array.|null>, Array.>|null>} items + * @returns {void} + * @access public + */ + this.reset_to = (item, ...items) => { + anp.preload(item, (item, asynchronous, ok) => { + if(ok){ + // [...item.childNodes].forEach(subitem => { + // item.removeChild(subitem); + // }); + item.innerHTML = ``; + setTimeout(() => { + console.log(item); + self.set_direct_to(item, ...items); + }, 1); + }; + }); + } + /** * @param {!(Object.|Array.)} inputs * @returns {Array.} @@ -349,42 +395,77 @@ export const Components = (function(){ * @returns {Array.} * @access public */ - this.buttons = (buttons, attributes = null, tag = "div") => self.group(buttons, Utils.get_dictionary([attributes, { + this.buttons = (buttons, attributes = null, tag = "div") => self.group(buttons.map(button => ["button", button]), Utils.get_dictionary([attributes, { class : Attributes.join_classes("buttons", Utils.get_value(["class", "classes"], attributes)) }]), tag); - /** - * @param {?(Object.)} [attributes = null] - * @param {?(Object.)} [own_attributes = null] - * @returns {Array.} - * @access public - */ - this.input = (attributes = null, own_attributes = null) => ["input", { - ...Utils.get_dictionary(attributes), - ...Utils.get_dictionary(own_attributes), - built : true - }]; - /** * @param {?(Object.)} [attributes = null] * @returns {Array.} * @access public * @returns */ - this.number = (attributes = null) => { + this.number = (attributes = null) => ["input", anp.attr.get_for_input([attributes, { + type : "number", + class : Attributes.join_classes("input-field input-number", Utils.get_value(["class", "classes"], attributes)) + }], ["classes"])]; - /** @type {string} */ - const classes = Attributes.join_classes("input-field input-number", Utils.get_value(["class", "classes"], attributes)); + /** + * @param {!string} tag + * @param {?(string|Array.)} i18n + * @param {?string} text + * @param {?(Object.|Array.)} [inputs = null] + * @returns {Array.|null} + * @access public + */ + this.i18n_text = (tag, i18n, text, inputs = null) => ( + i18n ? self.i18n(i18n, tag, [{text : text}, inputs]) : + !Check.is_null_or_undefined(text) ? ["legend", inputs, text] : + null); - Attributes.remove(attributes = Utils.get_dictionary(attributes), ["class", "classes"]); + /** + * @param {!Object.} attributes + * @returns {Array.|Array.|null>, Array.>|null} + * @access private + */ + const get_check_text = attributes => ( + !Check.is_null_or_undefined(attributes.i18n) ? ["i18n", [attributes.i18n, "span", attributes.title]] : + !Check.is_null_or_undefined(attributes.title) ? ["span", null, attributes.title] : + null); - return ["span", {class : classes}, [ - ["input", { - ...attributes, - type : "number" - }] - ]]; - }; + /** + * @param {!(Object.|Array.)} attributes + * @returns {Array.|Array.|null>, Array.>} + * @access public + */ + this.checkbox = attributes => ["label", { + class : "checkbox", + ...(attributes.id ? {for : attributes.id} : {}) + }, [ + ["input", attributes = anp.attr.get_for_input([attributes, { + type : "checkbox", + class : Attributes.join_classes("input-field input-check", Utils.get_value(["class", "classes"], attributes)) + }], ["classes", "placeholder"])], + ["icon", ["checkbox"]], + get_check_text(attributes) + ]]; + + /** + * @param {!(Object.|Array.)} attributes + * @returns {Array.|Array.|null>, Array.>} + * @access public + */ + this.radio = attributes => ["label", { + class : "radio-button", + ...(attributes.id ? {for : attributes.id} : {}) + }, [ + ["input", attributes = anp.attr.get_for_input([attributes, { + type : "radio", + class : Attributes.join_classes("input-field input-radio", Utils.get_value(["class", "classes"], attributes)) + }], ["classes", "placeholder"])], + ["icon", ["radio_button"]], + get_check_text(attributes) + ]]; constructor(); diff --git a/Public/ecma/Components/BaseComponent.ecma.js b/Public/ecma/Components/BaseComponent.ecma.js index 39a1397..97c3bad 100644 --- a/Public/ecma/Components/BaseComponent.ecma.js +++ b/Public/ecma/Components/BaseComponent.ecma.js @@ -224,14 +224,23 @@ export const BaseComponent = (function(){ /** @type {Array.} */ const licenses = anp.settings.get(["application_licenses", "application_license", "licenses", "license"], inputs, []), /** @type {Object.} */ - attributes = get_attributes(inputs); + attributes = get_attributes(inputs), + /** @type {string} */ + link = anp.settings.get([ + "application_web", "application_website", "application_link", "application_url", + "web", "website", "link", "url" + ], inputs, "/"), + /** @type {string|Array.} */ + logo = anp.settings.get(["application_logo", "logo"], inputs, "/images/AnP.png"), + /** @type {string} */ + name = anp.settings.get(["application_name", "name"], inputs, "AnP"); return anp.components.set(["div", attributes, [ ["header", null, [ - ["h1", {class : "logo", title : "AnP"}, [ - ["a", {href : "https://anp.k3y.pw/", target : "_blank"}, [ - ["image", {sources : "/images/AnP.png", title : "AnP"}], - ["span", {class : "text"}, "AnP"] + ["h1", {class : "logo", title : name}, [ + ["a", {href : link, target : "_blank"}, [ + ["image", {sources : logo, title : name}], + ["span", {class : "text"}, name] ]] ]] ]], diff --git a/Public/ecma/Components/FormsComponent.ecma.js b/Public/ecma/Components/FormsComponent.ecma.js index 2652401..1403c42 100644 --- a/Public/ecma/Components/FormsComponent.ecma.js +++ b/Public/ecma/Components/FormsComponent.ecma.js @@ -1,5 +1,9 @@ "use strict"; +import {Check} from "../Utils/Check.ecma.js"; +import {Utils} from "../Utils/Utils.ecma.js"; +import {Attributes} from "../Application/Attributes.ecma.js"; + /** * @typedef {import("../Application/AnP.ecma.js").AnP} AnP */ @@ -56,22 +60,137 @@ export const FormsComponent = (function(){ * @access public */ this.build = inputs => { - return anp.comp.set(["form", {}, [ + + /** @type {string|null} */ + const i18n = Utils.get_value("i18n", inputs), + /** @type {string|null} */ + text = Utils.get_value("text", inputs, Check.is_array(i18n) ? i18n[0] : i18n); + + return ["form", { + class : "form", + on_submit : (item, event) => false, + method : "get", + action : "#" + }, [ ["fieldset", null, [ - ["legend", null, "LEGEND"], - ["p", null, "PARAGRAPH"], - ["div", {class : "structure"}, Utils.get_value("structure", inputs, []).reduce((structure, item) => { + anp.comp.i18n_text("legend", i18n, text), + anp.comp.i18n_text("p", Attributes.i18n_add_suffix(i18n, "text"), Utils.get_value("description", inputs, text)), + ["div", {class : "structure"}, Utils.get_array(Utils.get_value("structure", inputs, [])).reduce((structure, item, i) => { + + /** @type {[string|null, boolean]} */ + const [type, is_array] = ( + Check.is_array(item) ? [Check.is_string(item[0]) ? item[0] : null, true] : + Check.is_dictionary(item) ? [Check.is_string(item.type) ? item.type : null, false] : + [null, false]), + /** @type {string|null} */ + name = Utils.get_value(["name", "i18n"], item), + /** @type {string|null} */ + i18n = Utils.get_value(["i18n", "name"], item), + /** @type {string} */ + id = Utils.get_value("id", item) || anp.random_chain(), + /** @type {string|null} */ + text = Utils.get_value("text", item); + + structure.push(["div", { + data_field : Utils.get_value("name", item, id), + data_i : i + }, [ + ["label", {for : id}, [ + anp.comp.i18n(i18n, "span", text), + anp.comp.i18n_text("span", + Attributes.i18n_add_suffix(i18n, "description"), + Utils.get_value("description", item, text) + ) + ]], + ["span", {class : "input"}, anp.comp[type] ? [anp.comp[type]([item, {id : id}])] : null], + ["ul", {class : "errors"}] + ]]); + return structure; }, [])], ["ul", {class : "errors"}], - anp.comp.buttons() + anp.comp.buttons(Utils.get_array(Utils.get_value(["buttons", "actions"], inputs, []))) ]] - ]]); + ]]; + }; + + /** + * @param {!(HTMLFormElement|HTMLElement)} form + * @returns {Object.} + * @access public + */ + this.get_data = form => { + + /** @type {Object.} */ + const data = {}; + + (form = FormsComponent.get(form)) && + form.querySelectorAll("[name]").forEach(item => { + + /** @type {string} */ + const name_attribute = item.getAttribute("name"), + /** @type {boolean} */ + is_array = name_attribute.slice(-2) == "[]", + /** @type {string} */ + name = is_array ? name_attribute.slice(0, -2) : name_attribute; + + if(is_array) + (data[name] || (data[name] = [])).push(self.get_value(item)); + else + data[name] = self.get_value(item); + + }); + + return data; + }; + + /** + * @param {!HTMLElement} item + * @returns {any|null} + * @access public + */ + this.get_value = (item) => { + + /** @type {string} */ + const type = item.getAttribute("type"), + /** @type {string} */ + tag = item.tagName.toLowerCase(); + + return ( + type == "number" ? Number(item.value) : + type == "date" ? new Date(item.value) : + ["radio", "checkbox"].includes(type) ? item.checked : + item.value); }; constructor(); }; + /** + * @param {!HTMLElement} form + * @returns {HTMLFormElement|null} + * @access public + * @static + */ + FormsComponent.get = form => { + + if(form){ + + /** @type {HTMLFormElement} */ + const child = form.querySelector && form.querySelector("form.form"); + + if(child) + form = child; + else + while(( + (form.tagName && form.tagName.toLowerCase() != "form") || + (form.classList && !form.classList.contains("form")) + ) && (form = form.parentNode)); + }; + + return form || null; + }; + return FormsComponent; })(); \ No newline at end of file diff --git a/Public/ecma/Managers/EventsManager.ecma.js b/Public/ecma/Managers/EventsManager.ecma.js index 36f8ae6..fb5e42c 100644 --- a/Public/ecma/Managers/EventsManager.ecma.js +++ b/Public/ecma/Managers/EventsManager.ecma.js @@ -25,18 +25,31 @@ export const EventsManager = (function(){ */ const EventsManager = function(inputs = null){ - /** @type {Array.} */ - const events = []; + /** @type {Array.>} */ + const events = [], + /** @type {EventsManager} */ + self = this; /** @type {boolean} */ this.autoexecute = Utils.get_value("autoexecute", inputs, false); + this.times = Utils.get_value("times", inputs, 0); /** * @param {...any} [parameters] * @returns {Array.} * @access public */ - this.execute = (...parameters) => events.map(callback => callback ? callback(...parameters) : null); + this.execute = (...parameters) => events.map((event, i) => { + + let value = null; + + if(event){ + value = Utils.execute(event[0], ...parameters); + self.times && ++ event[1] >= self.times && (events[i] = null); + }; + + return value; + }); /** * @param {!anp_events_manager_callback} callback @@ -53,7 +66,9 @@ export const EventsManager = (function(){ while(++ i < l) if(!events[i]) break; - events[i] = callback; + events[i] = [callback, 0]; + + self.autoexecute && self.execute(); return i; }; diff --git a/Public/ecma/Utils/Check.ecma.js b/Public/ecma/Utils/Check.ecma.js index e1519c2..806f886 100644 --- a/Public/ecma/Utils/Check.ecma.js +++ b/Public/ecma/Utils/Check.ecma.js @@ -133,5 +133,13 @@ export const Check = (function(){ */ Check.is_number = item => typeof item == "number"; + /** + * @param {?any} item + * @returns {boolean} + * @access public + * @static + */ + Check.is_integer = item => Check.is_number(item) && item == item >> 0; + return Check; })(); \ No newline at end of file diff --git a/Public/scss/AnP.builder.scss b/Public/scss/AnP.builder.scss index fe3a6ff..074fd28 100644 --- a/Public/scss/AnP.builder.scss +++ b/Public/scss/AnP.builder.scss @@ -4,19 +4,26 @@ &,button,input,select,textarea{color : map-deep-get($color, $mode, fore);} button,input,select,textarea{background-color : map-deep-get($color, $mode, input-back);} [role=link],[data-role=link],a[href]{ - &[disabled]{color : map-deep-get($color, grey);} + // &[disabled]{color : map-deep-get($color, grey);} &[readonly]{color : map-deep-get($color, $mode, fore);} &:not([disabled],[readonly]){ color : map-deep-get($color, $mode, primary); &:hover{color : map-deep-get($color, $mode, secondary);} } } - [role=button],[data-role=button],button,[type=button],[type=submit],[type=reset]{ - &[disabled]{ - border-color : map-deep-get($color, grey); - color : map-deep-get($color, grey); - box-shadow : 0em 0em .4em inset map-deep-get($color, grey); + .checkbox,.radio-button{&:not([data-disabled]){ + color : mix(map-deep-get($color, $mode, fore), map-deep-get($color, $mode, primary), 50%); + &:hover>[type=checkbox]~span{ + color : mix(map-deep-get($color, $mode, fore), map-deep-get($color, $mode, secondary), 50%); } + &[data-readonly]{color : map-deep-get($color, $mode, fore);} + }} + [role=button],[data-role=button],button,[type=button],[type=submit],[type=reset]{ + // &[disabled]{ + // border-color : map-deep-get($color, grey); + // color : map-deep-get($color, grey); + // box-shadow : 0em 0em .4em inset map-deep-get($color, grey); + // } &[readonly]{ border-color : map-deep-get($color, $mode, fore); color : map-deep-get($color, $mode, fore); @@ -33,6 +40,11 @@ } } } + textarea,[type=text],[type=number],[type=date],[type=password]{&:not([disabled]){ + border-color : mix(map-deep-get($color, $mode, fore), map-deep-get($color, $mode, primary), 50%); + &:focus,&:hover{border-color : mix(map-deep-get($color, $mode, fore), map-deep-get($color, $mode, secondary), 50%);} + &[readonly]{border-color : map-deep-get($color, $mode, fore);} + }} header,footer{box-shadow : 0em 0em 1em map-deep-get($color, $mode, back), 0em 0em 1.25em map-deep-get($color, $mode, back), @@ -58,16 +70,50 @@ font-family : $font-icon; } + .checkbox,.radio-button{input{display : none;}} + a[href]{text-decoration : none;} - [role=link],[role=button],[data-role=link],[data-role=button],a[href],button,[type=button],[type=submit],[type=reset]{&:not([disabled],[readonly]){ - cursor : pointer; + [role=link],[data-role=link],a[href], + [role=button],[data-role=button],button,[type=button],[type=submit],[type=reset]{ + &:not([disabled],[readonly]){ + cursor : pointer; + transition-duration : $transition-out; + transition-property : color; + &:hover{transition-duration : $transition-in;} + } + &[disabled]{color : map-deep-get($color, grey);} + } + .checkbox,.radio-button{ + &>input:not([disabled],[readonly]){&~span{ + cursor : pointer; + transition-duration : $transition-out; + transition-property : color; + }} + &:hover>input:not([disabled],[readonly]){&~span{ + transition-duration : $transition-in; + }} + &>input[disabled]{color : map-deep-get($color, grey);} + } + &.anp{ + [role=link],[data-role=link],a[href], + [role=button],[data-role=button],button,[type=button],[type=submit],[type=reset]{ + &[disabled]{color : map-deep-get($color, grey);} + } + } + textarea,[type=text],[type=number],[type=date],[type=password]{&:not([disabled],[readonly]){ transition-duration : $transition-out; - transition-property : color; - &:hover{transition-duration : $transition-in;} + transition-property : color,border-color; + &:focus{ + outline : none; + transition-duration : $transition-in; + } }} - [role=button],[data-role=button],button,[type=button],[type=submit],[type=reset],[type=text],[type=number],[type=date],[type=password],textarea{ + [role=button],[data-role=button], + button,[type=button],[type=submit],[type=reset], + textarea,[type=text],[type=number],[type=date],[type=password]{ padding : .1em .4em; border-width : .1em; + color : map-deep-get($color, grey); border-style : solid; border-color : map-deep-get($color, grey); border-radius : $border-radius; @@ -77,11 +123,20 @@ transition-property : color,border-color,background-color,box-shadow; }} + textarea,select,[type=text],[type=number],[type=date],[type=password]{ + width : 100%; + box-sizing : border-box; + } + .group{ &>*{&,&>*{border-radius : 0em;}} &>:first-child{&,&>:first-child{border-radius : $border-radius 0em 0em $border-radius;}} &>:last-child{&,&>:last-child{border-radius : 0em $border-radius $border-radius 0em;}} } + .buttons{ + width : 100%; + text-align : center; + } [data-visible=false]{display : none;} @@ -220,4 +275,45 @@ right : 0em; } + form.form{ + display : block; + position : relative; + &>fieldset{ + border : none; + &>legend{ + font-size : 1.5em; + font-weight : 900; + } + } + .structure{ + display : table; + width : 100%; + box-sizing : border-box; + &>div{ + display : table-row; + &>*{ + display : table-cell; + padding : 1em .3em; + } + &>:first-child{ + padding-left : 1em; + width :30%; + min-width : 30%; + max-width : 50%; + text-align : right; + span{display : block;} + &>:first-child{ + font-weight : 900; + &::after{content : ":";} + } + &>:last-child{font-size : .85em;} + } + &>:nth-child(2){width : 100%;} + &>:last-child{ + padding-right : 1em; + } + } + } + } + } \ No newline at end of file diff --git a/Public/scss/AnP.icons.scss b/Public/scss/AnP.icons.scss index f230685..0e827d3 100644 --- a/Public/scss/AnP.icons.scss +++ b/Public/scss/AnP.icons.scss @@ -33,4 +33,13 @@ &[data-gui-mode=#{$mode}] [data-icon=gui_mode]::before{content : unicode($code); font-family : "FA6FS";} } + .checkbox input{ + &+[data-icon]::before{content : unicode("f0c8"); font-family : "FA6FR";} + &:checked+[data-icon]::before{content : unicode("f14a"); font-family : "FA6FR";} + } + .radio-button input{ + &+[data-icon]::before{content : unicode("f111"); font-family : "FA6FR";} + &:checked+[data-icon]::before{content : unicode("f192"); font-family : "FA6FR";} + } + } \ No newline at end of file diff --git a/version b/version index 6812f81..05b19b1 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.0.3 \ No newline at end of file +0.0.4 \ No newline at end of file