sdc_client 0.158.8 → 0.159.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/LICENSE +21 -0
- package/dist/index.js +49 -24
- package/dist/ugly.index.js +2 -1
- package/dist/ugly.index.js.LICENSE.txt +1 -8
- package/gulp/gulp.jsx +12 -42
- package/package.json +39 -31
- package/src/index.js +27 -7
- package/src/simpleDomControl/AbstractSDC.js +24 -11
- package/src/simpleDomControl/sdc_controller.js +7 -4
- package/src/simpleDomControl/sdc_dom_events.js +5 -10
- package/src/simpleDomControl/sdc_events.js +3 -3
- package/src/simpleDomControl/sdc_main.js +34 -13
- package/src/simpleDomControl/sdc_model.js +209 -84
- package/src/simpleDomControl/sdc_params.js +0 -3
- package/src/simpleDomControl/sdc_server_call.js +21 -4
- package/src/simpleDomControl/sdc_test_utils.js +0 -1
- package/src/simpleDomControl/sdc_utils.js +59 -7
- package/src/simpleDomControl/sdc_view.js +21 -1
- package/.github/workflows/node.js.yml +0 -38
- package/.idea/inspectionProfiles/Project_Default.xml +0 -17
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -403
- package/.readthedocs.yaml +0 -13
- package/.tool-versions +0 -1
- package/SimpleDomControlClient.iml +0 -12
- package/docs/api-reference.rst +0 -225
- package/docs/conf.py +0 -11
- package/docs/controllers.rst +0 -228
- package/docs/events-and-dom.rst +0 -120
- package/docs/getting-started.rst +0 -143
- package/docs/index.rst +0 -22
- package/docs/models.rst +0 -351
- package/docs/overview.rst +0 -66
- package/docs/requirements.txt +0 -1
- package/eslint.config.js +0 -60
- package/gulpfile.jsx +0 -25
- package/jest.config.mjs +0 -197
- package/test/controller.test.js +0 -93
- package/test/dist.test.js +0 -127
- package/test/model.test.js +0 -330
- package/test/models/Author.js +0 -145
- package/test/models/Book.js +0 -112
- package/test/models/BookContent.js +0 -114
- package/test/models/SdcUser.js +0 -75
- package/test/models/src.js +0 -8
- package/test/sdc_model_dates.ai.test.js +0 -57
- package/test/sdc_server_call.ai.test.js +0 -267
- package/test/utils.js +0 -88
- package/test/view.test.js +0 -159
- package/test-setup.js +0 -4
- package/webpack.config/webpack.default.config.cjs +0 -22
- package/webpack.config/webpack.development.config.cjs +0 -14
- package/webpack.config/webpack.production.config.cjs +0 -11
package/dist/ugly.index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
var e={};let t;function n(){return new Promise(function(e){e()})}function r(e){return(e=(e=e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)).replace(/[0-9]+/g,e=>`-${e}`)).replace(/^[-]/g,"")}function s(e){return e.replace(/-./g,e=>`${e[1].toUpperCase()}`)}e.d=(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);const o=(e,t)=>{let n=t,r=Object.getOwnPropertyNames(e.prototype).concat(Object.getOwnPropertySymbols(e.prototype));for(;""!==n.name;)Object.getOwnPropertyNames(n.prototype).concat(Object.getOwnPropertySymbols(n.prototype)).forEach(t=>{t.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)||r.includes(t)||(r.push(t),Object.defineProperty(e.prototype,t,Object.getOwnPropertyDescriptor(n.prototype,t)))}),n=Object.getPrototypeOf(n)};function i(e,t,n){return $.ajax({url:t,type:n||"POST",xhr:function(){var e=$.ajaxSettings.xhr();return e.upload&&e.upload.addEventListener("progress",l,!1),e},data:e,cache:!1,contentType:!1,processData:!1,beforeSend:function(e,t){(function(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)})(t.type)||this.crossDomain||e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}})}function l(e){if(e.lengthComputable){var t=Math.round(e.loaded/e.total*100),n=$(".progress-container");100===t?n.hide():n.show(),t+="%",n.find(".progress-bar").css({width:t}).text(t)}}function a(e,t=null){return"string"!=typeof e?e:t&&void 0!==t[e]?"function"==typeof t[e]?t[e].bind(t):t[e]:e.match(/^(true|false)$/)?"true"===e:"undefined"!==e?"none"===e.toLowerCase()?null:e.match(/^-?\d+$/)?parseInt(e):e.match(/^-?\d+\.?\d+$/)?parseFloat(e):e.match(/^(['][^']*['])|(["][^"]*["])$/)?e.substr(1,e.length-2):e:void 0}function c(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function u(e){e.find(".has-error").removeClass("has-error").find(".alert-danger").remove(),e.find(".non-field-errors").remove()}function d(e,t){t=$("<div>").append(t),e.find(".has-error").removeClass("has-error").find(".alert-danger").safeRemove(),e.find(".non-field-errors").safeRemove();let n=t.find("input[type=file]").parent();e.find("input[type=file]").parent().each(function(e){$(this).replaceWith(n[e])});let r=0===t.find(".non-field-errors").insertAfter(e.find(".hidden-form-fields")).length;return t.find(".has-error").each(function(){r=!1;let t=$(this),n=t.data("auto-id"),s=e.find(".form-group."+n);s.addClass("has-error"),s.find(".form-input-container").append(t.find(".alert-danger"))}),r}function h(e){let{type:t,name:n}=e;return n&&""!==n?"hidden"===t?(r=$(e).val()).toLowerCase().match(/^(true|false)$/)?"true"===r.toLowerCase():"undefined"!==r?"none"===r.toLowerCase()?null:r.match(/^-?\d+$/)?parseInt(r,10):r.match(/^-?\d+\.?\d+$/)?parseFloat(r):r.match(/^(['][^']*['])|(["][^"]*["])$/)?r.substring(1,r.length-1):r:void 0:"checkbox"===t?e.checked:"file"===t?e.files[0]:$(e).val():null;var r}function m(e,t){let{type:n,name:r}=e;if(r&&""!==r)if("checkbox"===n)e.checked=!!t;else if("file"===n){if(t instanceof File&&"undefined"!=typeof DataTransfer){let n=new DataTransfer;n.items.add(t),e.files=n}}else t instanceof ae?$(e).val(t.id):t instanceof le?$(e).val(`[${t.getIds().join(",")}]`):(null===t&&(t=""),$(e).val(t));return null}function f(e,t=null){return Object.fromEntries(Object.entries(e).filter(([e,t])=>e!==A).map(([e,n])=>{if("string"==typeof n&&n.startsWith("SDC_JSON_MODEL=["))try{const{pk:t,fields:r}=JSON.parse(n.slice(16,-1));return[e,{...r,id:t,id:t}]}catch{}return[e,a(n,t)]}))}function p(e,t=null){return f(e.data(),t)}const y=["onbeforeunload","onunload"],g=Object.keys(window).filter(e=>/^on/.test(e)&&!y.includes(e)).map(e=>e.slice(2));function v(e,t,n){let r;switch(e){case"mouseleave":case"mouseout":case"mouseenter":case"mousein":return r=document.elementFromPoint(t.clientX,t.clientY),n!==r&&!n.contains(r);default:return!0}}function w(e){let t=e.type;e.hasOwnProperty("namespace")&&e.namespace&&e.namespace.length&&(t+=`.${e.namespace}`);let n=$(e.target),r=null,s=!1,o=!1;for(e.stopImmediatePropagation=()=>o=!0,e.stopPropagation=()=>o=s=!0;n.length;){let i=n.attr(`sdc_${t}`);if(i&&v(t,e,n[0])){if(!r&&(r=Q(n),!r))return;for(;r;){if(i.split(" ").forEach(o=>{if(s)return;let i=null;if("function"==typeof o)i=o;else if("function"==typeof r[o])i=r[o];else if("string"==typeof o&&o.startsWith("this.event_")){if(i=r.getEvents()[t],!i)return;if(i=i[o.slice(11)],!i)return}i&&i.call(r,n,e)}),o)return;r=r._parentController}}if(s)return;n=n.parent()}return{res:!0}}function b(e){if(e._isEventsSet)return;const t=e.getEvents();for(let n in t)if(t.hasOwnProperty(n)){let r=t[n];for(let t in r)r.hasOwnProperty(t)&&e.find(t).each(function(){let e=$(this),r=e.attr(`sdc_${n}`)||null;r=r?r.split(" "):[];const s=`this.event_${t}`;-1===r.indexOf(s)&&(r.push(s),e.attr(`sdc_${n}`,r.join(" ")))})}}let R=[],N={};function C(e,t){if(e){let n=s(t._tagName);e._childController[n]||(e._childController[n]=[]),e._childController[n].push(t)}return t._parentController=e}function O(e,t,n,r){let s=[];r=function(e,t){e=(e=e.concat(N[t][1])).filter((e,t,n)=>n.indexOf(e)===t);let n=!0;for(;n;){n=!1;for(let t of e)for(let r of N[t][1])e.includes(r)||(e.push(r),n=!0)}return e}(r,n);for(let e of r)s.push(N[e][0]);let i=new(function(e,...t){let n={[e.name]:class{constructor(...n){let r={};t.forEach(e=>{let t;Object.assign(this,t=new e),t._tagName=e.prototype._tagName,t._isMixin=!0,r[e.name]=t}),Object.assign(this,new e),this._mixins=r}static get name(){return e.name}static className(){return this.name}get mixins(){return this._mixins}}}[e.name];return o(n,e),t.forEach(e=>{o(n,e)}),n}(N[n][0],...s));return i._tagName=n,C(e,i),i.$container=t,function(e,t){!function(e,t,n){e&&"function"==typeof e.onInit&&(e.params=p(t,n._parentController))}(t,e,t)}(t,i),i}function S(e,t,n,r){if(R.includes(n)){let o=s(n);return window[o]||(window[o]=O(e,t,n,r)),window[o].$container=t,window[o]}return O(e,t,n,r)}function F(e,t){const r=function(e){return function(e){let t={args:{}};return e.contentUrl&&(t=V(e),e.contentUrl=t.url),Promise.all([D(e,t.args)]).then(function(e){let t=e[0];if(t)try{return $(t)}catch{return $("<div></div>").append(t)}return null})}(e).then(t=>!e.onLoad||e._onLoadDone?t:(e._onLoadDone=!0,(e.onLoad(t)||n()).then(()=>t)))}(e).then(function(t){return function(e,t){return W(e,t).then(function(t){if(t=t||!0,e.willShow){let n=e.willShow();if(n instanceof Promise)return n.then(function(){return t})}return t})}(e,t)}).then(()=>function(e,t){return X(null,e,t)}(e,t)).catch(function(t){return W(e,t)});return e.load_async?Promise.resolve():r}function E(e){const t=function(e){let t=[];for(;e;)e._isEventsSet=!1,t.unshift(e),e=e._parentController;return t}(e.controller[0]),n=t.concat(e.controller.slice(1));for(let t of n)b(t),t.onRefresh(e.controller[0])}function k(e,t){let n=Boolean(e);return n?e.uuids.has(t._uuid)||(e.uuids.add(t._uuid),e.controller.push(t)):e={uuids:new Set([t._uuid]),controller:[t]},{isRunningProcess:n,refreshProcess:e}}let P={},x={};function L(e,t){return j(e),x.hasOwnProperty(e)?t[x[e]]?void P[e].push(t):console.log("No event handler: "+e,t):console.log("No event: "+e,t)}function j(e,t){t||(t=e),x[e]||(x[e]=t,P[e]=[])}function I(e){for(let t in P)if(P.hasOwnProperty(t))for(let n=P[t].length-1;n>=0;n--)e===P[t][n]&&P[t].splice(n,1)}function q(e){let t=Array.apply(null,arguments);if(e=t.shift(),!P.hasOwnProperty(e)||!x.hasOwnProperty(e))return n();let r=P[e],s=x[e],o=[];for(let e=0;e<r.length;e++){let n=r[e][s].apply(r[e],t);void 0!==n&&o.push(n)}return Promise.all(o)}let T={};const A="_controller_",M="_sdc_controller_";function U(e,t,n){if(!e)return[];let r=e.children(),s=[];return r.each(function(e,r){let o=$(r),i=o.prop("tagName").toLowerCase().split("_");$.inArray(i[0],t)>=0?s.push({tag:i[0],super:i.splice(1)||[],dom:o}):i[0].startsWith("this.")?o.addClass(`_bind_to_update_handler sdc_uuid_${n._uuid}`):s=s.concat(U(o,t,n))}),s}function D(e,t){const{contentUrl:n,_tagName:r,contentReload:s}=e;return n?T[r]?Promise.resolve(T[r]):(t.VERSION=we.VERSION,t._method="content",$.get(n,t).then(function(e){return s||(T[r]=e),e}).catch(function(t){throw 301===t.status&&q("_RedirectOnView",t.responseJSON["url-link"]),"function"==typeof e.confirmPageLoaded&&q("navLoaded",{controller_name:()=>t.status}),`<sdc-error data-code="${t.status}">${t.responseText}</sdc-error>`})):Promise.resolve(!1)}function J(e,t,n=null){return t=t||e.data(A),G(we.tagNames,e,t,n)}function V(e){let t=e.contentUrl;if(e&&0===e._urlParams.length){let n,r=/%\(([^)]+)\)\w/gm;for(e._urlParams=[];n=r.exec(t);)e._urlParams.push(n[1]),e.contentReload=!0}let{args:n,params:r}=function(e,t){const n=p(t,e),[r,s]=Object.entries(n).reduce(([t,n],[r,s])=>(e._urlParams.includes(r)?t[r]=s:n[r]=s,[t,n]),[{},{}]);return{params:r,args:s}}(e,e.$container);return e._urlParams.length&&(t=function(e,t,n){for(let r in e._urlParams)if(e._urlParams.hasOwnProperty(r)){let s=e._urlParams[r],o=RegExp("%\\("+s+"\\)\\w","gm");const i=n[s];i||console.warn(`${s} is not set for controller ${e._tagName}`),t=t.replace(o,i)}return t}(e,t,r)),e.parsedContentUrl=t,{url:t,args:n}}function Q(e){return e.hasClass(M)?e.data(`${A}`):e.closest(`.${M}`).data(`${A}`)}function B(e,t,n,r,s){let o=e.data(A);return o?J(e,o,s):(o=S(r,e,t,n),e.data(A,o),e.addClass(M),F(o,s))}function W(e,t,n=null){if(t&&t.length>0){e.$container.empty(),e.$container.attr(e._tagName,"");for(let t in e._mixins)e.$container.attr(e._mixins[t]._tagName,"");e.$container.append(t)}return J(e.$container,e,n)}function G(e,t,n,r){return new Promise(s=>{let o=U(t,e,n),i=o.length;if(0===i)return s();for(let e=0;e<o.length;e++)B(o[e].dom,o[e].tag,o[e].super,n,r).then(()=>{if(i--,0===i)return s()})})}function z({$element:e,id:t=[],parent:n=null}){t.push(function(e){if(3===e[0].nodeType)return`TEXT__${e[0].nodeValue}`;const t=[e[0].tagName];return"INPUT"===e[0].nodeName&&[["name",""],["type","text"],["id",""]].forEach(([n,r])=>{const s=e.attr(n)??r;s&&t.push(s)}),t.join("__")}(e));const r={$element:e,id:t.join("::"),depth:t.length,idx:0,getRealParent:()=>n,getIdx:function(){return this.idx=Math.max(0,(this.getRealParent()?.getIdx()??-1)+e.index()+1),this.idx},op:null,parent:n};return r.getIdx.bind(r),[r].concat(e.contents().toArray().map(e=>z({$element:$(e),id:t.slice(),parent:r})).flat())}function K(e,t){const n=z({$element:t}),r=z({$element:e});n.map((e,t)=>e.idx=t),r.map((e,t)=>e.idx=t);const s=Math.max(...r.concat(n).map(e=>e.depth)),o=H(n,r,s);let i=[];window.MAIN=t,window.OPS=o,o.forEach((e,t)=>{const{op:n,$element:r,idx:s}=e;if("keep_counterpart"===n.type){if(n.counterpart.getIdx()!==s){const t=e.getBefore();t?n.counterpart.$element.insertAfter(t.$element):e.getRealParent().$element.prepend(n.counterpart.$element)}!function(e,t){const n=e[0].attributes??[],r=t[0].attributes??[];[...n].forEach(n=>{t.is(`[${n.name}]`)||e.removeAttr(n.name)}),[...r].forEach(t=>{t.name.startsWith("data")||e.attr(t.name)===t.value||e.attr(t.name,t.value)}),e.removeData(),Object.entries(t.data()).forEach(([t,n])=>{e.data(t,n)})}(n.counterpart.$element,r),r.hasClass(M)&&(r.data(A).$container=n.counterpart.$element,r.data(A,null)),i.push(r)}else if("delete"===n.type)r.safeRemove();else if("insert"===n.type){const{after:t,target:n}=e.op;t?r.insertAfter(t.$element):n&&n.$element.prepend(r)}}),i.forEach(e=>e.safeRemove())}function H(e,t,n){return t.filter(e=>e.depth===n&&!e.op).forEach(t=>{const n=e.find(e=>!e.op&&e.id===t.id);if(n){const e=(t,n)=>{t.op={type:"keep",idx:n.idx},n.op={type:"keep_counterpart",counterpart:t},t=t.parent,n=n.parent,!t||t.op||n?.op||e(t,n)};e(n,t)}}),n>1?H(e,t,n-1):(e.forEach((t,n)=>{if(!t.op){const r=(e[n-1]?.op.idx??-1)+1;t.op={type:"delete",idx:r}}}),t.forEach((e,n)=>{if(e.getBefore=()=>function(e,n){const r=e.depth;for(;n>=1&&e.depth>=r;)if((e=t[n-=1]).depth===r)return"keep_counterpart"===e.op.type?e.op.counterpart:e;return null}(e,n),e.getRealParent=()=>{return(t=e).parent?"keep_counterpart"===t.parent.op.type?t.parent.op.counterpart:t.parent:null;var t},!e.op){const t=e.getRealParent(),n="insert"===t?.op.type?"insert_ignore":"insert";e.op={type:n,target:t,after:e.getBefore()}}}),[...e,...t].sort((e,t)=>(e.op?.idx??e.idx)-(t.op?.idx??t.idx)))}function X(e,t,n=null){if(t||(t=Q(e)),!t)return Promise.resolve();const{refreshProcess:r,isRunningProcess:s}=k(n,t);return e??=t.$container,G(we.tagNames,e,t,n).then(()=>function(e,t,n){return function(e,t,n){const r=[];return t.find(`._bind_to_update_handler.sdc_uuid_${e._uuid}`).each(function(){const t=$(this);let s;if(t.hasClass("_with_handler"))s=t.data("handler");else{let t=this.tagName.toLowerCase().replace(/^this./,"");e[t]&&(s=e[t])}if("function"==typeof s){const n=f(t.data(),e);s=s.bind(e)(n)}s&&r.push(Promise.resolve(s).then(r=>{let s=$("<div></div>");return s.append(r),""===t.html()&&t.append("<div></div>"),we.reconcile(e,s,t.children(),n)}))}),Promise.all(r)}(e,t??e.$container,n)}(t,e,r).then(()=>{s||E(r)}))}const Y={};function Z(e,t){Y[e]=t}function ee(e){return Y[e]}const te=25e3,ne="_connecting_process",re=e=>Object.assign(Object.create(Object.getPrototypeOf(e)),structuredClone(e));class se extends Error{constructor(e){"string"==typeof e&&(e={msg:e,is_error:!0,header:"Error"}),super(e.msg),this.msg=e.msg,this.header=e.header,this.is_error=e.is_error,this.html=e.html}}class oe{constructor({name:e,url:t}){this.name=e,this.url=t,this.content=null}async load(e=!1){return!e&&this.content||(this.content=await new Promise((e,t)=>{$.get(this.url).then(e).catch(()=>{e("")})})),this.content}async text(){return this.load()}static isValid(e){return!(null===e||"object"!=typeof e||Array.isArray(e)||e instanceof File||"string"!=typeof e.url||"string"!=typeof e.name)}}function ie(e){const t=parseInt(e??-1,10);return Number.isNaN(t)?-1:t}class le{constructor(e,t={}){return this.valuesList=[],this.loaded=!1,this.modelName=e,this.modelQuery=t??{},this._onNoOpenRequests=[],this._isConnected=!1,this._isConnectingProcess=!1,this._autoReconnect=!0,this.socket=null,this.openRequest={},this.modelId=0,this.onUpdate=()=>{},this.onCreate=()=>{},new Proxy(this,{get:(e,t)=>"symbol"==typeof t||isNaN(t)?e[t]:e.valuesList[t],set:(e,t,n)=>isNaN(t)?(e[t]=n,!0):(e.valuesList[t]=n,!0)})}[Symbol.iterator](){let e=-1;return{next:()=>(++e,e<this.valuesList.length?{value:this.valuesList[e],done:!1}:{value:null,done:!0})}}set on_create(e){this.onCreate=e}set on_update(e){this.onUpdate=e}setIds(e){const t=this._setIds(e),n={id__in:t.map(e=>e.id)};return this.setFilter(n),t}cloneObject;_setIds(e){if(null===e||""===e||Array.isArray(e)&&0===e.length)return this.valuesList=[],this.valuesList;if(e instanceof le)return this.valuesList=e.valuesList.map(re),this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;if(e instanceof ae)return this.valuesList=[re(e)],this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;let t,n=Number.NaN;if(Number.isInteger(e))n=e;else if(e instanceof Array){const n=e.map(e=>parseInt(e));n.some(Number.isNaN)||(t=n)}else if("string"==typeof e){const r=e.split(",").map(e=>parseInt(e));r.some(Number.isNaN)?n=parseInt(e):t=r}if(Number.isNaN(n)){if(t){this.valuesList=this.valuesList.filter(e=>t.includes(e.id));const e=this.getIds();t.filter(t=>!e.includes(t)).forEach(e=>{this.valuesList.push(new(ee(this.modelName))({id:e}))})}}else this.valuesList=this.valuesList.filter(e=>n===e.id),0===this.valuesList.length&&(this.new().id=n);return this.valuesList}getIds(){return this.valuesList.map(e=>e.id)}get length(){return this.valuesList.length}byId(e){if(null!==e){const t=ie(e);return this.valuesList.find(e=>e.id===t)??null}return null}setFilter(e){return this.modelQuery=e,this}addFilter(e){return this.modelQuery=Object.assign({},this.modelQuery,e),this}new(e={}){const t=new(ee(this.modelName))(e);return t._setQuerySet(this,!1),this.valuesList.push(t),t}load(e=null){return this.valuesList=[],this.modelQuery=e??this.modelQuery,this._sendLoad()}update({modelQuery:e=null,item:t=null}){this.modelQuery=e??this.modelQuery;let n=t?{id:t.id}:this.modelQuery;return this._sendLoad(n)}delete({pk:e=null,id:t=null,elem:n=null}){if(e??=t,null===(e=n?n.id:e))throw new Error("pk or elem must be set");const r=c();return this.isConnected().then(()=>new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"delete",event_id:r,args:{model_name:this.modelName,model_query:this.modelQuery,id:e,pk:e}})),this.openRequest[r]=[t,n]}))}_sendLoad(e=null){return this.isConnected().then(()=>{const t=c();return new Promise((n,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"load",event_id:t,args:{model_name:this.modelName,model_query:e??this.modelQuery}})),this.openRequest[t]=[e=>{this.loaded=!0,n(e)},r]})})}_sendListView({modelQuery:e={},cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this.view({modelQuery:e,cbResolve:t,cbReject:n,templateContext:r,eventType:"list_view"})}view({viewName:e="html_list_template",modelQuery:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={},eventType:o="named_view"}){let i=$('<div class="container-fluid">');return this.isConnected().then(()=>{const l=c();this.socket.send(JSON.stringify({event:"model",event_type:o,event_id:l,args:{view_name:e,model_name:this.modelName,model_query:t,template_context:s}})),this.openRequest[l]=[e=>{i.append(e.html),we.refresh(i),n&&n(e)},e=>{r&&r(e)}]}),i}_sendDetailView({pk:e=null,id:t=null,cbResolve:n=null,cbReject:r=null,templateContext:s={}}){e??=t,e=ie(e);let o=$('<div class="container-fluid">');return this.isConnected().then(()=>{const t=c();this.socket.send(JSON.stringify({event:"model",event_type:"detail_view",event_id:t,args:{model_name:this.modelName,model_query:this.modelQuery,id:e,pk:e,template_context:s}})),this.openRequest[t]=[e=>{o.append(e.html),we.refresh(o),n&&n(e)},e=>{r&&r(e)}]}),o}getForm({modelObj:e,eventType:t,formName:n,$divForm:r,cbResolve:s,cbReject:o,formId:i}){const l=c(),a=e.id??-1;this.isConnected().then(()=>{this.socket.send(JSON.stringify({event:"model",event_type:t,event_id:l,args:{model_name:this.modelName,id:a,pk:a,form_name:n}}))});const u=null===a||-1===a?"create":"edit";this.openRequest[l]=[t=>{r.append(t.html);let o=r.closest("form").addClass(`sdc-model-${u}-form sdc-model-form ${i}`).data("model",e).data("model_pk",a).data("form_name",n);e.addForm(o),o.length>0&&!o[0].hasAttribute("sdc_submit")&&o.attr("sdc_submit","submitModelFormDistributor"),we.refresh(r).then(()=>null),s&&s(t)},e=>{o&&o(e)}]}async get(e=null,t=!1){if(t){const t=e?.id??this.modelQuery?.id;return e&&this.setFilter(e),this.byId(t)??this.new(e||this.modelQuery)}if(await this.load(e),1!==this.length)throw new Error(`model query returns ${this.length} but only 1 expected.`);return this.addFilter({id:this.valuesList[0].id}),this.valuesList[0]}detailView({pk:e,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this._sendDetailView({id:e,cbResolve:t,cbReject:n,templateContext:r})}listView({modelQuery:e={},searchValues:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={}}){return this._sendListView({modelQuery:Object.assign({},this.modelQuery,e,{__search_values:t}),cbResolve:n,cbReject:r,templateContext:s})}save({pk:e=null,id:t=null,formName:n="edit_form",data:r=null}={}){e??=t;const s=ie(e);return this.isConnected().then(()=>{let e;if(s>-1){const t=this.byId(s);if(!t)return Promise.reject(new se(`Element not found with ID: ${s}`));e=[t]}else e=this.valuesList;let t=[];return e.forEach(e=>{const s=c();t.push(new Promise((t,o)=>{this._readFiles(e).then(i=>{const l=r?{...r}:e.serialize();l.id=e.id,this.socket.send(JSON.stringify({event:"model",event_type:"save",event_id:s,args:{form_name:n,model_name:this.modelName,model_query:this.modelQuery,data:l,id:l.id,pk:l.id,files:i}})),this.openRequest[s]=[e=>{let n="string"==typeof e.data.instance?JSON.parse(e.data.instance):e.data.instance;e.data.instance=this._parseServerRes(n),t(e)},o]})}))}),Promise.all(t)})}create({elem:e=null,data:t=null}={}){const n=c();return e||(e=this.new(t)),this.isConnected().then(()=>new Promise((r,s)=>{this._readFiles(e).then(o=>{this.socket.send(JSON.stringify({event:"model",event_type:"create",event_id:n,args:{model_name:this.modelName,model_query:this.modelQuery,data:t??e?.serialize()??{},files:o}})),this.openRequest[n]=[t=>{let n="string"==typeof t.data.instance?JSON.parse(t.data.instance):t.data.instance;e&&(e.id=n[0]?.id||n[0]?.pk),t.data.instance=this._parseServerRes(n)[0],r(t)},s]})}))}isConnected(){return new Promise((e,t)=>{if(this._isConnected)e();else if(this._isConnectingProcess&&this.openRequest[ne]){const[n,r]=this.openRequest[ne];this.openRequest[ne]=[()=>{n(),e()},()=>{r(),t()}]}else this._isConnectingProcess=!0,this.openRequest[ne]=[()=>{},()=>{}],this._connectToServer().then(()=>{e(this._checkConnection())})})}close(){this.socket&&(this._autoReconnect=!1,this.socket.onclose=()=>{},this.socket.close(),delete this.socket),this.valuesList.forEach(e=>{e._onClose()})}_readFiles(e){let t=[],n={};return e?(Object.keys(e.constructor.fields).forEach(r=>{const s=e[r];s instanceof File&&t.push(new Promise(async(e,t)=>{const o=c();this.openRequest[o]=[e,t];const i=await s.arrayBuffer();let l=new Uint8Array(i),a=Math.ceil(l.length/te);n[r]={id:o,file_name:s.name,field_name:r,content_length:s.size};for(let e=0;e<a;++e){const t=Array.from(l.slice(te*e,te*(e+1)));this.socket.send(JSON.stringify({event:"model",event_type:"upload",event_id:o,args:{chunk:t,idx:e,number_of_chunks:a,file_name:s.name,field_name:r,content_length:s.size,content_type:s.type,model_name:this.modelName,model_query:this.modelQuery}}))}}))}),Promise.all(t).then(()=>n)):Promise.resolve(n)}async _onMessage(e){let t=JSON.parse(e.data);if(t.is_error)this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][1](new se(t)),this._closeOpenRequest(t.event_id)),(t.msg||t.header)&&q("pushErrorMsg",t.header||"",t.msg||""),"connect"===t.type&&(this.openRequest[ne][1](new se(t)),this._closeOpenRequest(ne),this._autoReconnect=!1,this.socket.close());else{if((t.msg||t.header)&&q("pushMsg",t.header||"",t.msg||""),"connect"===t.type)this._isConnected=!0,this._isConnectingProcess=!1,this.openRequest[ne][0](t),this._closeOpenRequest(ne);else if(["load","named_view","detail_view"].includes(t.type)){const e=JSON.parse(t.args.data);t.args.data=await this._parseServerRes(e)}else if("on_update"===t.type||"on_create"===t.type){const e=JSON.parse(t.args.data);let n,r=await this._parseServerRes(e);n="on_create"===t.type?this.onCreate:this.onUpdate,n(r),t.args.data=r}let e=t.data?.instance;e&&(t.data.instance=JSON.parse(t.data.instance)),this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][0](t),this._closeOpenRequest(t.event_id))}}noOpenRequests(){return new Promise(e=>{if(0===Object.keys(this.openRequest).length)return e();this._onNoOpenRequests.push(e)})}_closeOpenRequest(e){delete this.openRequest[e],0===Object.keys(this.openRequest).length&&(this._onNoOpenRequests.forEach(e=>e()),this._onNoOpenRequests=[])}_connectToServer(){return new Promise(e=>{const t=`${this.modelName}`+(this.modelId>0?`/${this.modelId}`:"");"https:"===window.location.protocol?this.socket=new WebSocket(`wss://${window.location.host}/sdc_ws/model/${t}`):this.socket=new WebSocket(`ws://${window.location.host}/sdc_ws/model/${t}`),this.socket.onmessage=this._onMessage.bind(this),this.socket.onclose=e=>{console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`),this._isConnected=!1;for(const[t,n]of Object.entries(this.openRequest))n[1](e);this.openRequest={},setTimeout(()=>{this._autoReconnect&&this._connectToServer().then(()=>{})},1e3)},this.socket.onerror=e=>{if(console.error(`Model Socket encountered error: ${e} Closing socket`),this._isConnected)try{this.socket.close()}catch(e){}},this.socket.onopen=()=>{e()}})}_checkConnection(){const e=c();return new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"connect",event_id:e,args:{model_name:this.modelName,model_query:this.modelQuery}})),this.openRequest[e]=[t,n]})}_parseServerRes(e){const t=[];for(const n of e){const e=ee(this.modelName);if(!e)throw new Error(`${this.modelName} is no SdcModel. mybe the models ar not importad.`);const r=new e({id:n.id??n.pk,...n.fields}),s=this.byId(r.id);s?(s.setValues(r),t.push(s)):(this.valuesList.push(r),r._setQuerySet(this,!0),t.push(r))}return this.valuesList.sort((e,t)=>e._id-t._id),t}}class ae{static fields={};constructor(e){this._id=null,this._forms=[],this.loaded=!1,this.formId=c(),this.modelName=e}static querySet(e=null,t=null){return t?t.querySet(this.modeName,e):new le(this.modeName,e)}addForm(e){const t=this._onChange.bind(this);this._forms.push(e),e&&e.on("input.formWatcher change.formWatcher","input, select, textarea",t)}_onChange(e){const{name:t}=e.target;this.constructor.fields[t]&&this[`set${t}`](h(e.target))}_updateForm(e){const t=this;this._forms.forEach(n=>{n.find(`[name="${e}"]`).each(function(){m(this,t[e])})})}setValues(e={}){throw new Error("setValues() must be implemented by subclass")}_setQuerySet(e,t){this._querySet=new WeakRef(e),this.loaded=t}get querySet(){return this._querySet.deref()}save({formName:e="edit_form",data:t=null}={}){return this._querySet.deref().save({pk:this.id,formName:e,data:t})}create({data:e=null}={}){return this._querySet.deref().create({elem:this,data:e})}delete(){return this._querySet.deref().delete({elem:this})}load(){return this._querySet.deref().update({item:this})}update(){return this.load()}get id(){return this._id}set id(e){this._id=e}set pk(e){this.id=e}get pk(){return this._id}close(){return this._querySet.deref().close()}_onClose(){Object.keys(this.constructor.fields).filter(e=>this[`_${e}`]instanceof le).forEach(e=>this[`_${e}`].close())}detailView({cbResolve:e=null,cbReject:t=null,templateContext:n={}}){return this._querySet.deref().detailView({pk:this.id,cbResolve:e,cbReject:t,templateContext:n})}serialize(){return Object.entries(this.constructor.fields).reduce((e,[t,n])=>{const r=this[t];if(r instanceof le)if(n.many_to_many||n.one_to_many)e[t]=r.getIds();else{const n=r.getIds();n.length>0?e[t]=n[0]:e[t]=null}else n.is_relation&&r instanceof ae?e[t]=r.id??null:e[t]=r;return e},{})}toJson(){const e={};for(let t in this.constructor.fields){const n=this[t];n instanceof File?e[t]=n.name:e[t]=n instanceof ae?n.id:n instanceof le?n.getIds():n}return e}syncFormToModel(e){return this.syncForm(e)}_resolveForms(e){return e&&e.hasClass(this.formId)?e:$(`.${this.formId}`)}syncModelToForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields;e.each(function(){const e=ie($(this).data("model_pk"));if(t.id===e)for(let e of this.elements){let r=e.name;r&&""!==r&&n[r]&&m(e,t[r])}})}syncForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields,r={};function s(e,s){n[e]&&(t[e]=s),r[e]=s}return e.each(function(){const e=ie($(this).data("model_pk"));if(t.id===e||null===t.id&&-1===e){for(let e of this.elements)s(e.name,h(e));return t}}),r}form({cbResolve:e=null,cbReject:t=null}={}){return null===this.id||-1===this.id?this._createForm({cbReject:t,cbResolve:e}):this._editForm({cbReject:t,cbResolve:e})}_createForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"create_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}_editForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"edit_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}namedForm({formName:e,cbResolve:t=null,cbReject:n=null}){let r=$('<div class="container-fluid">');return this._querySet.deref().getForm({modelObj:this,eventType:"named_form",formName:e,$divForm:r,cbResolve:t,cbReject:n,formId:this.formId}),r}validate(e,t){const n=function(e,t){const{type:n,required:r,max_length:s,is_relation:o,many_to_many:i,one_to_many:l,many_to_one:a,one_to_one:c,related_model:u}=t;if(r&&(null==e||""===e))return"This field is required";if(null==e||""===e)return null;if((i||l||a||c)&&(!(e instanceof le)||e.modelName!==u))return"string"==typeof e&&(e=JSON.parse(e)),(i||a)&&Array.isArray(e)&&e.some(e=>!Number.isNaN(parseInt(e)))?null:"object"!=typeof e&&Number.isNaN(parseInt(e))?"Must be object or ID":null;switch(n){case"CharField":case"TextField":if("string"!=typeof e)return"Must be a string";if(s&&e.length>s)return`Max length is ${s}`;break;case"IntegerField":case"AutoField":case"BigIntegerField":if(!isFinite(parseInt(e)))return"Must be an integer";break;case"FloatField":case"DecimalField":if(!isFinite(parseFloat(e)))return"Must be a number";break;case"BooleanField":if("boolean"!=typeof e)return"Must be a boolean";break;case"DateField":case"DateTimeField":if(isNaN(Date.parse(e)))return"Must be a valid date";break;case"EmailField":if("string"!=typeof e||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))return"Invalid email";break;case"URLField":try{new URL(e)}catch{return"Invalid URL"}break;case"UUIDField":if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(e))return"Invalid UUID";break;case"JSONField":if("object"!=typeof e)return"Must be JSON object";break;case"FileField":if(!(oe.isValid(e)||e instanceof File||e instanceof oe))return"Must be a valid file"}return null}(e,t);if(n)throw new Error(n)}parseValue(e,t){const{type:n,many_to_many:r,one_to_many:s,many_to_one:o,one_to_one:i}=t;if(null===e)return null;if((r||s||o||i)&&e&&"string"==typeof e)return JSON.parse(e);switch(n){case"CharField":case"TeextField":case"UUIDField":case"EmailField":return`${e}`;case"IntegerField":case"AutoField":case"BigIntegerField":return parseInt(e,10);case"FloatField":case"DecimalField":return parseFloat(e);case"BooleanField":return!!e;case"DateField":case"DateTimeField":return Date.parse(e);case"URLField":return new URL(e);case"FileField":if(null==e)return null;if("string"==typeof e)return null;if(oe.isValid(e))return new oe(e);if(e instanceof oe)return new oe(e);if("undefined"!=typeof File&&e instanceof File)return t.max_size&&e.size>t.max_size?`File too large (max ${t.max_size} bytes)`:t.allowed_types&&!t.allowed_types.includes(e.type)?`Invalid file type (${e.type})`:e;break;case"JSONField":if("object"==typeof e)return e;if("string"==typeof e)return JSON.parse(e)}return e}}let ce=!1,ue=!1,de=null,he={};function me(){return window.SERVER_CALL_VIA_WEB_SOCKET?new Promise(e=>ce?e():ue?void setTimeout(()=>{me().then(()=>{e()})},200):e(pe())):Promise.resolve(!0)}function fe(){window.SERVER_CALL_VIA_WEB_SOCKET&&function(){if(ce){ce=!1;try{de.close()}catch(e){}}}()}function pe(){return ue=!0,new Promise(e=>{de="https:"===window.location.protocol?new WebSocket(`wss://${window.location.host}/sdc_ws/ws/`):new WebSocket(`ws://${window.location.host}/sdc_ws/ws/`),de.onmessage=function(e){_e(JSON.parse(e.data))},de.onclose=function(){ce&&console.error("SDC Socket closed unexpectedly"),ce=!1;for(const[e,t]of Object.entries(he))t[1]({}),delete he[e];setTimeout(()=>{pe()},1e3)},de.onerror=function(e){if(console.error("Socket encountered error: ",e.message,"Closing socket"),ce)try{de.close()}catch(e){}},de.onopen=function(){ce=!0,ue=!1,e()}})}function _e(e){if(e||(e={}),e.is_error)(e.msg||e.header)&&q("pushErrorMsg",e.header||"",e.msg||""),e.id&&he[e.id]&&(he[e.id][1](e.data||null),delete he[e.id]);else if((e.msg||e.header)&&q("pushMsg",e.header||"",e.msg||""),e.type&&"sdc_recall"===e.type)e.id&&he[e.id]&&(he[e.id][0](e.data),delete he[e.id]);else if(e.type&&"sdc_event"===e.type){let t=e.event;t&&q(t,e.payload)}else e.type&&"sdc_redirect"===e.type&&q("onNavLink",e.link)}class ye{constructor(){this._uuid=c(),this.contentUrl="",this.contentReload=!1,this.parsedContentUrl=null,this.events=[],this.load_async=!1,this._isEventsSet=!1,this._allEvents=null,this._params={},this._urlParams=[],this._models=[],this._cssUrls=[],this.afterShow=()=>{console.warn("afterShow is deprecated!!")},this._mixins={},this._tagName=Object.getPrototypeOf(this)._tagName??"",this._childController={},this._parentController=null,this._onLoadDone=!1,this.$container=null,this._isMixin=!1}get params(){return this._params}set params(e){this._params=e}_runLifecycle(e,t){we.DEBUG&&!this._isMixin&&console.debug(e,this._tagName);let n=[];if(!this._isMixin){this._isMixin=!0;for(let r in this._mixins){let s=this._mixins[r];"function"==typeof s[e]&&n.push(s[e].apply(this,t))}return Promise.all(n).then(()=>{this._isMixin=!1})}}onInit(){we.DEBUG&&!this._isMixin&&console.debug(Array.apply(null,arguments),this._tagName)}get parentController(){return this._parentController}get childController(){return this._childController}onLoad(){return this._runLifecycle("onLoad",arguments)}willShow(){return this._runLifecycle("willShow",arguments)}onRefresh(){return this._runLifecycle("onRefresh",arguments)}onRemove(){return this._runLifecycle("onRemove",arguments),!0}noOpenModelRequests(){return Promise.all(this._models.map(e=>e.noOpenRequests()))}remove(){for(const e of this._models)e.close();let e=this._childController;for(let t in e)if(e.hasOwnProperty(t))for(let n of e[t])if(!n.remove())return!1;if(!this.onRemove||this.onRemove()){I(this);const e=s(this._tagName);if(this._parentController._childController[e]){let t=this._parentController._childController[e];for(let e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)}return this.$container.remove(),!0}return!1}controller_name(){return this._tagName.replace(/-./g,e=>` ${e[1].toUpperCase()}`).replace(/^./g,e=>`${e.toUpperCase()}`)}addEvent(e,t,n){this.getEvents(),this._allEvents[e]=this._allEvents[e]||{},this._allEvents[e][t]=n}getEvents(){if(this._allEvents)return this._allEvents;let e=[];e=e.concat(this.events);for(let t in this._mixins){let n=this._mixins[t];Array.isArray(n.events)&&(e=e.concat(n.events))}return this._allEvents=_.merge(...e)}post(e,t){return we.post(this,e,t)}get(e,t){return we.get(this,e,t)}submitForm(e,t,n){return we.submitFormAndUpdateView(this,e,t,n)}serverCall(e,t){let n=this.contentUrl.match(/sdc_view\/([^/]+)/i);if(n&&!(n.length<2))return function(e,t,n,r,s){return window.SERVER_CALL_VIA_WEB_SOCKET?function(e,t,n,r){let s=c();return me().then(()=>{de.send(JSON.stringify({event:"sdc_call",id:s,controller:t,app:e,function:n,args:r}))}),new Promise((e,t)=>{he[s]=[e,t]})}(e,t,r,s):function(e,t,n){return"object"!=typeof n&&Array.isArray(n)&&null===n&&(n={arg0:n}),n={data:JSON.stringify(n),_sdc_func_name:t,_method:"sdc_server_call"},$.post({url:e,data:n,beforeSend:function(e,t){e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}}).then(e=>{const t=e._return_data;return _e(t),t}).catch(e=>{const t=e.responseJSON||{};throw t.is_error=!0,_e(t),e})}(n,r,s)}(n[1],this._tagName,this.parsedContentUrl??this.contentUrl,e,t);console.error("To use the serverCall function the contentUrl must be set: "+this.name)}querySet(e,t={}){const n=new le(e,t);return this._models.push(n),n}newModel(e,t={}){return console.warn("newModel is deprecated and will soon be removed. Please use this.querySet(modelName, modelQuery)"),this.querySet(e,t)}find(e){return this.$container.find(e)}refresh(){return we.refresh(this.$container,this)}reload(){return we.reloadController(this)}reconcile(e,t=null){return we.reconcile(this,e,t)}submitModelFormDistributor(e,t){return"function"==typeof this._submitModelForm?this._submitModelForm(e,t):"function"==typeof this.submitModelForm?this.submitModelForm(e,t):this.defaultSubmitModelForm(e,t)}iterateAllChildren(){let e=this._childController,t=[];for(let n in e)if(e.hasOwnProperty(n))for(let r of e[n])t.push(r),t.push(...r.iterateAllChildren());return t}defaultSubmitModelForm(e,t){if(!this._isMixin){t.stopPropagation(),t.preventDefault();let{model:n,form_name:r}=e.data(),s=n.syncForm(e);return new Promise((t,o)=>{let i;i=null!==n.id&&n.id>=0?n.save({formName:r,data:s}):n.create({data:s}),i.then(n=>{u(e),this.submit_model_form_success&&this.submit_model_form_success(n[0]);for(const e of this.iterateAllChildren())e.submit_model_form_success&&e.submit_model_form_success(n[0]);t(n)}).catch(t=>{this.reconcile($(`<div class="container-fluid">${t.html}</div>`),e.find(".container-fluid").first()),this.submit_model_form_error&&this.submit_model_form_error(t);for(const e of this.iterateAllChildren())e.submit_model_form_error&&e.submit_model_form_error(t);o(t)})})}return Promise.resolve()}}const ge={classname:"class"};window.sdcDom=function(e,t,...n){if(!e)return"";const r=function(e,t){let n,r=!1;if("string"==typeof e)n=$(document.createElement(e));else{const t=`this.${e.name}`;n=$(document.createElement(t)),n.data("handler",e),r=!0}return t&&Object.entries(t).forEach(([e,t])=>{e.startsWith("on")?n[0].addEventListener(e.substring(2).toLowerCase(),t):(ge[e.toLowerCase()]&&(e=ge[e.toLowerCase()]),n[0].setAttribute(e,t))}),r&&n.addClass("_bind_to_update_handler _with_handler"),n}(e,t);for(const e of n)r.append(e);return r};let ve,we={CSRF_TOKEN:window.CSRF_TOKEN||"",LANGUAGE_CODE:window.LANGUAGE_CODE||"en",DEBUG:window.DEBUG||!1,VERSION:window.VERSION||"0.0",tagNames:[],Global:R,rootController:null,globalRootController:null,_isInit:!1,_origin_trigger:null,_globalControllerClasses:[],init_sdc:()=>{we._isInit||(we._isInit=!0,we._origin_trigger?fe():(we._origin_trigger=$.fn.trigger,$.fn.trigger=function(e){const t={}.hasOwnProperty.call(e,"type")?e.type:e;return g.includes(t)||(g.push(t),$(window).on(t,w)),we._origin_trigger.call(this,e)},we.updateJquery()),me(),function(){const e=$(window);g.forEach(t=>{e.off(t).on(t,w)})}(),we.rootController=we.rootController||new ye,we.globalRootController=we.globalRootController||new ye),we.tagNames=Object.keys(N);const e=$("<div></div>");R.forEach(t=>{const n=N[t][0];e.append(`<${n.prototype._tagName}></${n.prototype._tagName}>`)});const{refreshProcess:n}=k(null,we.rootController);return G(we.tagNames,e,we.globalRootController,n).then(()=>G(we.tagNames,(t||(t=$("body")),t),we.rootController,n).then(e=>(E(n),e)))},updateJquery:()=>{$.fn.safeReplace=function(e){return we.safeReplace($(this),e)},$.fn.safeEmpty=function(){return we.safeEmpty($(this))},$.fn.safeRemove=function(){return we.safeRemove($(this))}},controllerToTag:e=>r(e.name).replace(/-controller$/,""),registerGlobal:e=>{we.register(e);let t=e.prototype._tagName;R.push(t)},cleanCache:()=>{T={}},register:(e,t=!1)=>{let n=we.controllerToTag(e);return!N[n]||t?(N[n]=[e,[]],e.prototype._tagName=n,{addMixin:(...e)=>{for(let t of e){let e;"string"==typeof t?e=r(t):t&&(e=we.controllerToTag(t)),N[n][1].push(e)}}}):{addMixin:(...e)=>{}}},post:(e,t,n)=>(n||(n={}),n.CSRF_TOKEN=we.CSRF_TOKEN,we.ajax(e,t,n,$.post)),get:(e,t,n)=>we.ajax(e,t,n,$.get),ajax:(e,t,n,r)=>{n||(n={}),n.VERSION=we.VERSION,n._method=n._method||"api";const s=new Promise((o,i)=>r(t,n).then((t,n,r)=>{o(t,n,r),"redirect"===t.status?q("onNavLink",t["url-link"]):s.then(()=>{we.refresh(e.$container)})}).catch(i));return s},submitFormAndUpdateView:(e,t,n,r)=>{let s=new FormData(t);const o=e=>{e["url-link"]?q("onNavLink",e["url-link"]):window.location.href=e.url},l=new Promise((a,c)=>{i(s,n||t.action,r||t.method).then((t,n,r)=>{a(t,n,r),"redirect"===t.status?o(t):l.then(()=>{we.refresh(e.$container,e)})}).catch((e,t,n)=>{301===e.status?(e=e.responseJSON,o(e),a(e,t,n)):c(e,t,n)})});return l},submitForm:(e,t,n)=>{let r=new FormData(e);return new Promise((s,o)=>{i(r,t||e.action,n||e.method).then(s).catch(o)})},getController:e=>Q(e),safeEmpty:e=>(e.children().each(function(e,t){let n=$(t);we.safeRemove(n)}),e),safeReplace:(e,t)=>(t.insertBefore(e),we.safeRemove(e)),safeRemove:e=>(e.each(function(){let e=$(this);e.data(`${A}`)&&e.data(`${A}`).remove()}),e.find(`.${M}`).each(function(){const e=$(this).data(`${A}`);e&&e.remove()}),e.remove()),reloadController:e=>function(e){if(e.contentUrl){let t=V(e);return e.contentUrl=t.url,D(e,t.args)}return new Promise(e=>{e($())})}(e).then(t=>{let n=$(t);return we.reconcile(e,n)}),reconcile:(e,t,n=null,r=null)=>{if(!n){let n=e.$container.clone().empty();n.data(A,null),n.removeClass(M),n.append(t),t=n}n=n??e.$container;const{refreshProcess:s,isRunningProcess:o}=k(r,e);return X(t,e,s).then(()=>{var r;return K(t,n),(r=e)._childController={},r.find(`.${M}`).each(function(){const e=Q($(this));e===r&&C(r,e)}),o||E(s),e})},refresh:(e,t=null)=>X(e,t)},be=[];function $e(){if(!jest)throw new Error("JEST is not defined");0===be.length&&(ve=$.ajax.bind($),be.push(jest.spyOn($,"ajax")),be[0].mockImplementation(function(e){return ve(e).then(e=>e).catch(e=>e)}))}const Re=fe,Ne={get_controller:async function(e,t={},n=""){$e();const r=$("body");we.updateJquery(),r.safeEmpty();const s=$(`<${e}>${n}</${e}>`);for(const[e,n]of Object.entries(t))s.data(e,n);const o=$("<div></div>").append(s);r.append(o),we._isInit=!1,we.cleanCache(),await we.init_sdc();const i=we.getController(s);return i.navControllerPath=[e],i},getCsrfToken:function(){return function(e){if(document.cookie&&""!==document.cookie){const t=document.cookie.split(";");for(let n=0;n<t.length;n++){const r=t[n].trim();if(r.substring(0,10)===e+"=")return decodeURIComponent(r.substring(10))}}return""}("csrftoken")},controllerFromTestHtml:async function(e,t=null){$e();const n=$("body");we.updateJquery(),n.safeEmpty().append(e),we._isInit=!1,we.cleanCache(),await we.init_sdc();let r=we.rootController.iterateAllChildren();if(!t)return r;const s=r[0].onRefresh,o=jest.spyOn(r[0],"onRefresh");return new Promise(e=>{o.mockImplementation(function(){o.mockRestore();const t=s.apply(r[0],arguments);return e(r),t})})}};export{ye as AbstractSDC,ae as SdcModel,le as SdcQuerySet,I as allOff,we as app,a as checkIfParamNumberBoolOrString,u as clearErrorsInForm,S as controllerFactory,L as on,Z as registerModel,F as runControlFlowFunctions,d as setErrorsInForm,j as setEvent,Re as socketReconnect,Ne as test_utils,q as trigger};
|
|
1
|
+
/*! For license information please see ugly.index.js.LICENSE.txt */
|
|
2
|
+
let e;function t(){return new Promise(function(e){e()})}function n(e){return(e=(e=e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)).replace(/[0-9]+/g,e=>`-${e}`)).replace(/^[-]/g,"")}function r(e){return e.replace(/-./g,e=>`${e[1].toUpperCase()}`)}const s=(e,t)=>{let n=t,r=Object.getOwnPropertyNames(e.prototype).concat(Object.getOwnPropertySymbols(e.prototype));for(;""!==n.name;)Object.getOwnPropertyNames(n.prototype).concat(Object.getOwnPropertySymbols(n.prototype)).forEach(t=>{t.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)||r.includes(t)||(r.push(t),Object.defineProperty(e.prototype,t,Object.getOwnPropertyDescriptor(n.prototype,t)))}),n=Object.getPrototypeOf(n)};function o(e,t,n){return $.ajax({url:t,type:n||"POST",xhr:function(){var e=$.ajaxSettings.xhr();return e.upload&&e.upload.addEventListener("progress",i,!1),e},data:e,cache:!1,contentType:!1,processData:!1,beforeSend:function(e,t){(function(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)})(t.type)||this.crossDomain||e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}})}function i(e){if(e.lengthComputable){var t=Math.round(e.loaded/e.total*100),n=$(".progress-container");100===t?n.hide():n.show(),t+="%",n.find(".progress-bar").css({width:t}).text(t)}}function l(e,t=null){return"string"!=typeof e?e:t&&void 0!==t[e]?"function"==typeof t[e]?t[e].bind(t):t[e]:e.match(/^(true|false)$/)?"true"===e:"undefined"!==e?"none"===e.toLowerCase()?null:e.match(/^-?\d+$/)?parseInt(e):e.match(/^-?\d+\.?\d+$/)?parseFloat(e):e.match(/^(['][^']*['])|(["][^"]*["])$/)?e.substr(1,e.length-2):e:void 0}function a(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function c(e){e.find(".has-error").removeClass("has-error").find(".alert-danger").remove(),e.find(".non-field-errors").remove()}function u(e,t){t=$("<div>").append(t),e.find(".has-error").removeClass("has-error").find(".alert-danger").safeRemove(),e.find(".non-field-errors").safeRemove();let n=t.find("input[type=file]").parent();e.find("input[type=file]").parent().each(function(e){$(this).replaceWith(n[e])});let r=0===t.find(".non-field-errors").insertAfter(e.find(".hidden-form-fields")).length;return t.find(".has-error").each(function(){r=!1;let t=$(this),n=t.data("auto-id"),s=e.find(".form-group."+n);s.addClass("has-error"),s.find(".form-input-container").append(t.find(".alert-danger"))}),r}function d(e){let{type:t,name:n}=e;return n&&""!==n?"hidden"===t?(r=$(e).val()).toLowerCase().match(/^(true|false)$/)?"true"===r.toLowerCase():"undefined"!==r?"none"===r.toLowerCase()?null:r.match(/^-?\d+$/)?parseInt(r,10):r.match(/^-?\d+\.?\d+$/)?parseFloat(r):r.match(/^(['][^']*['])|(["][^"]*["])$/)?r.substring(1,r.length-1):r:void 0:"checkbox"===t?e.checked:"file"===t?e.files[0]:$(e).val():null;var r}const h=e=>String(e).padStart(2,"0");function f(e){if(null==e||""===e)return null;let t;if(e instanceof Date)t=e;else if("string"==typeof e&&/^\d{4}-\d{2}-\d{2}$/.test(e)){const[n,r,s]=e.split("-").map(Number);t=new Date(n,r-1,s)}else t=new Date(e);return isNaN(t.getTime())?null:t}function m(e){const t=f(e);return t?`${t.getFullYear()}-${h(t.getMonth()+1)}-${h(t.getDate())}`:""}function p(e,t){let{type:n,name:r}=e;if(r&&""!==r)if("datetime-local"===n)e.value=function(e){const t=f(e);return t?`${m(t)}T${h(t.getHours())}:${h(t.getMinutes())}`:""}(t);else if("date"===n)e.value=m(t);else if("checkbox"===n)e.checked=!!t;else if("file"===n){if(t instanceof File&&"undefined"!=typeof DataTransfer){let n=new DataTransfer;n.items.add(t),e.files=n}}else t instanceof ue?$(e).val(t.id):t instanceof ce?$(e).val(`[${t.getIds().join(",")}]`):(null===t&&(t=""),$(e).val(t));return null}function g(e,t=null){return Object.fromEntries(Object.entries(e).filter(([e,t])=>e!==U).map(([e,n])=>{if("string"==typeof n&&n.startsWith("SDC_JSON_MODEL=["))try{const{pk:t,fields:r}=JSON.parse(n.slice(16,-1));return[e,{...r,id:t}]}catch{}return[e,l(n,t)]}))}function y(e,t=null){return g(e.data(),t)}const v=["onbeforeunload","onunload"],w=Object.keys(window).filter(e=>/^on/.test(e)&&!v.includes(e)).map(e=>e.slice(2));function b(e,t,n){let r;switch(e){case"mouseleave":case"mouseout":case"mouseenter":return r=document.elementFromPoint(t.clientX,t.clientY),n!==r&&!n.contains(r);default:return!0}}function R(e){let t=e.type;Object.hasOwn(e,"namespace")&&e.namespace&&e.namespace.length&&(t+=`.${e.namespace}`);let n=$(e.target),r=null,s=!1,o=!1;for(e.stopImmediatePropagation=()=>o=!0,e.stopPropagation=()=>o=s=!0;n.length;){let i=n.attr(`sdc_${t}`);if(i&&b(t,e,n[0])){if(!r&&(r=W(n),!r))return;for(;r;){if(i.split(" ").forEach(o=>{if(s)return;let i=null;if("function"==typeof o)i=o;else if("function"==typeof r[o])i=r[o];else if("string"==typeof o&&o.startsWith("this.event_")){if(i=r.getEvents()[t],!i)return;if(i=i[o.slice(11)],!i)return}i&&i.call(r,n,e)}),o)return;r=r._parentController}}if(s)return;n=n.parent()}return{res:!0}}function C(e){const t=e.getEvents();for(let n in t)if(Object.hasOwn(t,n)){let r=t[n];for(let t in r)Object.hasOwn(r,t)&&e.find(t).each(function(){let e=$(this),r=e.attr(`sdc_${n}`)||null;r=r?r.split(" "):[];const s=`this.event_${t}`;-1===r.indexOf(s)&&(r.push(s),e.attr(`sdc_${n}`,r.join(" ")))})}}let N=[],O={};function S(e,t){if(e){let n=r(t._tagName);e._childController[n]||(e._childController[n]=[]),e._childController[n].push(t)}return t._parentController=e}function F(e,t,n,r){let o=[];r=function(e,t){e=(e=e.concat(O[t][1])).filter((e,t,n)=>n.indexOf(e)===t);let n=!0;for(;n;){n=!1;for(let t of e)for(let r of O[t][1])e.includes(r)||(e.push(r),n=!0)}return e}(r,n);for(let e of r)o.push(O[e][0]);let i=new(function(e,...t){let n={[e.name]:class{constructor(...n){let r={};t.forEach(e=>{let t;Object.assign(this,t=new e),t._tagName=e.prototype._tagName,t._isMixin=!0,r[e.name]=t}),Object.assign(this,new e),this._mixins=r}static get name(){return e.name}static className(){return this.name}get mixins(){return this._mixins}}}[e.name];return s(n,e),t.forEach(e=>{s(n,e)}),n}(O[n][0],...o));return i._tagName=n,S(e,i),i.$container=t,function(e,t){!function(e,t,n){if(!e)return!1;e.params=y(t,n._parentController)}(t,e,t)}(t,i),i}function k(e,t,n,s){if(N.includes(n)){let o=r(n);return window[o]||(window[o]=F(e,t,n,s)),window[o].$container=t,window[o]}return F(e,t,n,s)}function E(e,n){const r=function(e){return function(e){let t={args:{}};return e.contentUrl&&(t=B(e),e.contentUrl=t.url),Promise.all([V(e,t.args)]).then(function(e){let t=e[0];if(t)try{return $(t)}catch{return $("<div></div>").append(t)}return null})}(e).then(n=>!e.onLoad||e._onLoadDone?n:(e._onLoadDone=!0,(e.onLoad(n)||t()).then(()=>n)))}(e).then(function(t){return function(e,t){return z(e,t).then(function(t){if(t=t||!0,e.willShow){let n=e.willShow();if(n instanceof Promise)return n.then(function(){return t})}return t})}(e,t)}).then(()=>function(e,t){return Z(null,e,t)}(e,n)).catch(function(t){if("string"==typeof t||t instanceof $)return z(e,t);throw t});return e.load_async?Promise.resolve():r}function x(e){const t=function(e){let t=[];for(;e;)t.unshift(e),e=e._parentController;return t}(e.controller[0]),n=t.concat(e.controller.slice(1));for(let t of n)C(t),t.onRefresh(e.controller[0])}function I(e,t){let n=Boolean(e);return n?e.uuids.has(t._uuid)||(e.uuids.add(t._uuid),e.controller.push(t)):e={uuids:new Set([t._uuid]),controller:[t]},{isRunningProcess:n,refreshProcess:e}}let j={},P={};function L(e,t){return q(e),Object.hasOwn(P,e)?t[P[e]]?void j[e].push(t):console.log("No event handler: "+e,t):console.log("No event: "+e,t)}function q(e,t){t||(t=e),P[e]||(P[e]=t,j[e]=[])}function T(e){for(let t in j)if(Object.hasOwn(j,t))for(let n=j[t].length-1;n>=0;n--)e===j[t][n]&&j[t].splice(n,1)}function A(e){let n=Array.apply(null,arguments);if(e=n.shift(),!Object.hasOwn(j,e)||!Object.hasOwn(P,e))return t();let r=j[e],s=P[e],o=[];for(let e=0;e<r.length;e++){let t=r[e][s].apply(r[e],n);void 0!==t&&o.push(t)}return Promise.all(o)}let D={};const U="_controller_",M="_sdc_controller_";function J(e,t,n){if(!e)return[];let r=e.children(),s=[];return r.each(function(e,r){let o=$(r),i=o.prop("tagName").toLowerCase().split("_");$.inArray(i[0],t)>=0?s.push({tag:i[0],super:i.splice(1)||[],dom:o}):i[0].startsWith("this.")?o.addClass(`_bind_to_update_handler sdc_uuid_${n._uuid}`):s=s.concat(J(o,t,n))}),s}function V(e,t){const{contentUrl:n,_tagName:r,contentReload:s}=e;return n?D[r]?Promise.resolve(D[r]):(t.VERSION=$e.VERSION,t._method="content",$.get(n,t).then(function(e){return s||(D[r]=e),e}).catch(function(t){if(301===t.status){const n=t.responseJSON;return A("_RedirectOnView",n["url-link"]),s||(e.autoRedirect=n["url-link"]),"<p>Redirected</p>"}throw e.autoRedirect=null,"function"==typeof e.confirmPageLoaded&&A("navLoaded",{controller_name:()=>t.status}),`<sdc-error data-code="${t.status}">${t.responseText}</sdc-error>`})):Promise.resolve(!1)}function Q(e,t,n=null){return t=t||e.data(U),K($e.tagNames,e,t,n)}function B(e){let t=e.contentUrl;if(e&&0===e._urlParams.length){let n,r=/%\(([^)]+)\)\w/gm;for(e._urlParams=[];n=r.exec(t);)e._urlParams.push(n[1]),e.contentReload=!0}let{args:n,params:r}=function(e,t){const n=y(t,e),[r,s]=Object.entries(n).reduce(([t,n],[r,s])=>(e._urlParams.includes(r)?t[r]=s:n[r]=s,[t,n]),[{},{}]);return{params:r,args:s}}(e,e.$container);return e._urlParams.length&&(t=function(e,t,n){for(let r in e._urlParams)if(Object.hasOwn(e._urlParams,r)){let s=e._urlParams[r],o=RegExp("%\\("+s+"\\)\\w","gm");const i=n[s];i||console.warn(`${s} is not set for controller ${e._tagName}`),t=t.replace(o,i)}return t}(e,t,r)),e.parsedContentUrl=t,{url:t,args:n}}function W(e){return e.hasClass(M)?e.data(`${U}`):e.closest(`.${M}`).data(`${U}`)}function G(e,t,n,r,s){let o=e.data(U);return o?Q(e,o,s):(o=k(r,e,t,n),e.data(U,o),e.addClass(M),E(o,s))}function z(e,t,n=null){if(t&&t.length>0){e.$container.empty(),e.$container.attr(e._tagName,"");for(let t in e._mixins)e.$container.attr(e._mixins[t]._tagName,"");e.$container.append(t)}return Q(e.$container,e,n)}function K(e,t,n,r){return new Promise(s=>{let o=J(t,e,n),i=o.length;if(0===i)return s();for(let e=0;e<o.length;e++)G(o[e].dom,o[e].tag,o[e].super,n,r).then(()=>{if(i--,0===i)return s()})})}function H({$element:e,id:t=[],parent:n=null}){t.push(function(e){if(3===e[0].nodeType)return`TEXT__${e[0].nodeValue}`;const t=[e[0].tagName];return"INPUT"===e[0].nodeName&&[["name",""],["type","text"],["id",""]].forEach(([n,r])=>{const s=e.attr(n)??r;s&&t.push(s)}),t.join("__")}(e));const r={$element:e,id:t.join("::"),depth:t.length,idx:0,getRealParent:()=>n,getIdx:function(){return this.idx=Math.max(0,(this.getRealParent()?.getIdx()??-1)+e.index()+1),this.idx},op:null,parent:n};return r.getIdx.bind(r),[r].concat(e.contents().toArray().map(e=>H({$element:$(e),id:t.slice(),parent:r})).flat())}function X(e,t){const n=H({$element:t}),r=H({$element:e});n.map((e,t)=>e.idx=t),r.map((e,t)=>e.idx=t);const s=Math.max(...r.concat(n).map(e=>e.depth)),o=Y(n,r,s);let i=[];window.MAIN=t,window.OPS=o,o.forEach((e,t)=>{const{op:n,$element:r,idx:s}=e;if("keep_counterpart"===n.type){if(n.counterpart.getIdx()!==s){const t=e.getBefore();t?n.counterpart.$element.insertAfter(t.$element):e.getRealParent().$element.prepend(n.counterpart.$element)}!function(e,t){!function(e,t){if(!e||!t||!e._sdcListeners&&!t._sdcListeners)return;(e._sdcListeners??[]).forEach(([t,n])=>e.removeEventListener(t,n));const n=t._sdcListeners??[];n.forEach(([t,n])=>e.addEventListener(t,n)),e._sdcListeners=n}(e[0],t[0]);const n=e[0].attributes??[],r=t[0].attributes??[];[...n].forEach(n=>{t.is(`[${n.name}]`)||e.removeAttr(n.name)}),[...r].forEach(t=>{t.name.startsWith("data")||e.attr(t.name)===t.value||e.attr(t.name,t.value)}),e.removeData(),Object.entries(t.data()).forEach(([t,n])=>{e.data(t,n)})}(n.counterpart.$element,r),r.hasClass(M)&&(r.data(U).$container=n.counterpart.$element,r.data(U,null)),i.push(r)}else if("delete"===n.type)r.safeRemove();else if("insert"===n.type){const{after:t,target:n}=e.op;t?r.insertAfter(t.$element):n&&n.$element.prepend(r)}}),i.forEach(e=>e.safeRemove())}function Y(e,t,n){return t.filter(e=>e.depth===n&&!e.op).forEach(t=>{const n=e.find(e=>!e.op&&e.id===t.id);if(n){const e=(t,n)=>{t.op={type:"keep",idx:n.idx},n.op={type:"keep_counterpart",counterpart:t},t=t.parent,n=n.parent,!t||t.op||n?.op||e(t,n)};e(n,t)}}),n>1?Y(e,t,n-1):(e.forEach((t,n)=>{if(!t.op){const r=(e[n-1]?.op.idx??-1)+1;t.op={type:"delete",idx:r}}}),t.forEach((e,n)=>{if(e.getBefore=()=>function(e,n){const r=e.depth;for(;n>=1&&e.depth>=r;)if((e=t[n-=1]).depth===r)return"keep_counterpart"===e.op.type?e.op.counterpart:e;return null}(e,n),e.getRealParent=()=>{return(t=e).parent?"keep_counterpart"===t.parent.op.type?t.parent.op.counterpart:t.parent:null;var t},!e.op){const t=e.getRealParent(),n="insert"===t?.op.type?"insert_ignore":"insert";e.op={type:n,target:t,after:e.getBefore()}}}),[...e,...t].sort((e,t)=>(e.op?.idx??e.idx)-(t.op?.idx??t.idx)))}function Z(e,t,n=null){if(t||(t=W(e)),!t)return Promise.resolve();const{refreshProcess:r,isRunningProcess:s}=I(n,t);return e??=t.$container,K($e.tagNames,e,t,n).then(()=>function(e,t,n){return function(e,t,n){const r=[];return t.find(`._bind_to_update_handler.sdc_uuid_${e._uuid}`).each(function(){const t=$(this);let s;if(t.hasClass("_with_handler"))s=t.data("handler");else{let t=this.tagName.toLowerCase().replace(/^this./,"");e[t]&&(s=e[t])}if("function"==typeof s){const n=g(t.data(),e);s=s.bind(e)(n)}s&&r.push(Promise.resolve(s).then(r=>{let s=$("<div></div>");return s.append(r),""===t.html()&&t.append("<div></div>"),$e.reconcile(e,s,t.children(),n)}))}),Promise.all(r)}(e,t??e.$container,n)}(t,e,r).then(()=>{s||x(r)}))}const ee={};function te(e,t){ee[e]=t}function ne(e){return ee[e]}const re=25e3,se="_connecting_process";class oe extends Error{constructor(e){"string"==typeof e&&(e={msg:e,is_error:!0,header:"Error"}),super(e.msg),this.msg=e.msg,this.header=e.header,this.is_error=e.is_error,this.html=e.html}}class ie{constructor({name:e,url:t}){this.name=e,this.url=t,this.content=null}async load(e=!1){return!e&&this.content||(this.content=await new Promise((e,t)=>{$.get(this.url).then(e).catch(()=>{e("")})})),this.content}async text(){return this.load()}static isValid(e){return!(null===e||"object"!=typeof e||Array.isArray(e)||e instanceof File||"string"!=typeof e.url||"string"!=typeof e.name)}}function le(e){const t=parseInt(e??-1,10);return Number.isNaN(t)?-1:t}function ae(e){if(!e||"object"!=typeof e||e instanceof ue)return!1;const t=Object.keys(e);return!(0===t.length||!t.every(e=>"elem"===e||"data"===e)||"elem"in e&&null!==e.elem&&!(e.elem instanceof ue)||"data"in e&&null!==e.data&&"object"!=typeof e.data)}class ce{constructor(e,t={}){return this.valuesList=[],this.loaded=!1,this.modelName=e,this.modelQuery=t??{},this._onNoOpenRequests=[],this._isConnected=!1,this._isConnectingProcess=!1,this._autoReconnect=!0,this.socket=null,this.openRequest={},this.modelId=0,this.onUpdate=()=>{},this.onCreate=()=>{},this.onDelete=null,new Proxy(this,{get:(e,t)=>"symbol"==typeof t||isNaN(t)?e[t]:e.valuesList[t],set:(e,t,n)=>isNaN(t)?(e[t]=n,!0):(e.valuesList[t]=n,!0)})}[Symbol.iterator](){let e=-1;return{next:()=>(++e,e<this.valuesList.length?{value:this.valuesList[e],done:!1}:{value:null,done:!0})}}set on_create(e){this.onCreate=e}set on_update(e){this.onUpdate=e}set on_delete(e){this.onDelete=e}_removeIds(e){const t=this.valuesList.filter(t=>e.includes(t.id));return this.valuesList=this.valuesList.filter(t=>!e.includes(t.id)),t}setIds(e){const t=this._setIds(e),n={id__in:t.map(e=>e.id)};return this.setFilter(n),t}_setIds(e){if(null===e||""===e||Array.isArray(e)&&0===e.length)return this.valuesList=[],this.valuesList;if(e instanceof ce||e instanceof ue){const t=e instanceof ue?[e]:e.valuesList;return this.valuesList=t.map(e=>{const t=null!==e.id?this.byId(e.id):null;if(t)return t;const n=(e=>{const t=new e.constructor({});return t.setValues(e.serialize()),t})(e);return n._setQuerySet(this,!0),n}),this.valuesList}let t,n=Number.NaN;if(Number.isInteger(e))n=e;else if(e instanceof Array){const n=e.map(e=>parseInt(e));n.some(Number.isNaN)||(t=n)}else if("string"==typeof e){const r=e.split(",").map(e=>parseInt(e));r.some(Number.isNaN)?n=parseInt(e):t=r}if(Number.isNaN(n)){if(t){this.valuesList=this.valuesList.filter(e=>t.includes(e.id));const e=this.getIds();t.filter(t=>!e.includes(t)).forEach(e=>{this.valuesList.push(new(ne(this.modelName))({id:e}))})}}else this.valuesList=this.valuesList.filter(e=>n===e.id),0===this.valuesList.length&&(this.new().id=n);return this.valuesList}getIds(){return this.valuesList.map(e=>e.id)}get length(){return this.valuesList.length}byId(e){if(null!==e){const t=le(e);return this.valuesList.find(e=>e.id===t)??null}return null}setFilter(e){return this.modelQuery=e,this}addFilter(e){return this.modelQuery=Object.assign({},this.modelQuery,e),this}new(e={}){const t=new(ne(this.modelName))(e);return t._setQuerySet(this,!1),this.valuesList.push(t),t}load(e=null){return this.valuesList=[],this.modelQuery=e??this.modelQuery,this._sendLoad()}update({modelQuery:e=null,item:t=null}){this.modelQuery=e??this.modelQuery;let n=t?{id:t.id}:this.modelQuery;return this._sendLoad(n)}delete({pk:e=null,id:t=null,elem:n=null}){if(e??=t,null===(e=n?n.id:e))throw new Error("pk or elem must be set");const r=a();return this.isConnected().then(()=>new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"delete",event_id:r,args:{model_name:this.modelName,model_query:this.modelQuery,id:e,pk:e}})),this.openRequest[r]=[n=>{this._removeIds([le(e)]),t(n)},n]}))}_sendLoad(e=null){return this.isConnected().then(()=>{const t=a();return new Promise((n,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"load",event_id:t,args:{model_name:this.modelName,model_query:e??this.modelQuery}})),this.openRequest[t]=[e=>{this.loaded=!0,n(e)},r]})})}_sendListView({modelQuery:e={},cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this.view({modelQuery:e,cbResolve:t,cbReject:n,templateContext:r,eventType:"list_view"})}view({viewName:e="html_list_template",modelQuery:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={},eventType:o="named_view"}){let i=$('<div class="container-fluid">');return this.isConnected().then(()=>{const l=a();this.socket.send(JSON.stringify({event:"model",event_type:o,event_id:l,args:{view_name:e,model_name:this.modelName,model_query:t,template_context:s}})),this.openRequest[l]=[e=>{i.append(e.html),$e.refresh(i),n&&n(e)},e=>{r&&r(e)}]}),i}_sendDetailView({pk:e=null,id:t=null,cbResolve:n=null,cbReject:r=null,templateContext:s={}}){e??=t,e=le(e);let o=$('<div class="container-fluid">');return this.isConnected().then(()=>{const t=a();this.socket.send(JSON.stringify({event:"model",event_type:"detail_view",event_id:t,args:{model_name:this.modelName,model_query:this.modelQuery,id:e,pk:e,template_context:s}})),this.openRequest[t]=[e=>{o.append(e.html),$e.refresh(o),n&&n(e)},e=>{r&&r(e)}]}),o}getForm({modelObj:e,eventType:t,formName:n,$divForm:r,cbResolve:s,cbReject:o,formId:i}){const l=a(),c=e.id??-1;this.isConnected().then(()=>{this.socket.send(JSON.stringify({event:"model",event_type:t,event_id:l,args:{model_name:this.modelName,id:c,pk:c,form_name:n}}))});const u=null===c||-1===c?"create":"edit";this.openRequest[l]=[t=>{r.append(t.html);let o=r.closest("form").addClass(`sdc-model-${u}-form sdc-model-form ${i}`).data("model",e).data("model_pk",c).data("form_name",n);e.addForm(o),o.length>0&&!o[0].hasAttribute("sdc_submit")&&o.attr("sdc_submit","submitModelFormDistributor"),$e.refresh(r).then(()=>null),s&&s(t)},e=>{o&&o(e)}]}async get(e=null,t=!1){if(t){const t=e?.id??this.modelQuery?.id;return e&&this.setFilter(e),this.byId(t)??this.new(e||this.modelQuery)}if(await this.load(e),1!==this.length)throw new Error(`model query returns ${this.length} but only 1 expected.`);return this.addFilter({id:this.valuesList[0].id}),this.valuesList[0]}detailView({pk:e,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this._sendDetailView({id:e,cbResolve:t,cbReject:n,templateContext:r})}listView({modelQuery:e={},searchValues:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={}}){return this._sendListView({modelQuery:Object.assign({},this.modelQuery,e,{__search_values:t}),cbResolve:n,cbReject:r,templateContext:s})}save({pk:e=null,id:t=null,formName:n="edit_form",data:r=null}={}){e??=t;const s=le(e);return this.isConnected().then(()=>{let e;if(s>-1){const t=this.byId(s);if(!t)return Promise.reject(new oe(`Element not found with ID: ${s}`));e=[t]}else e=this.valuesList;let t=[];return e.forEach(e=>{const s=a();t.push(new Promise((t,o)=>{this._readFiles(e).then(i=>{const l=r?{...r}:e.serialize();l.id=e.id,this.socket.send(JSON.stringify({event:"model",event_type:"save",event_id:s,args:{form_name:n,model_name:this.modelName,model_query:this.modelQuery,data:l,id:l.id,pk:l.id,files:i}})),this.openRequest[s]=[e=>{let n="string"==typeof e.data.instance?JSON.parse(e.data.instance):e.data.instance;e.data.instance=this._parseServerRes(n),t(e)},o]})}))}),Promise.all(t)})}create(e=null){let{elem:t=null,data:n=null}=ae(e)?e:{data:e};n&&"object"==typeof n&&0===Object.keys(n).length&&(n=null);const r=a();return t||(t=this.new(n)),this.isConnected().then(()=>new Promise((e,s)=>{this._readFiles(t).then(o=>{this.socket.send(JSON.stringify({event:"model",event_type:"create",event_id:r,args:{model_name:this.modelName,model_query:this.modelQuery,data:n??t?.serialize()??{},files:o}})),this.openRequest[r]=[n=>{let r="string"==typeof n.data.instance?JSON.parse(n.data.instance):n.data.instance;t&&(t.id=r[0]?.id||r[0]?.pk),n.data.instance=this._parseServerRes(r)[0],e(n)},s]})}))}isConnected(){return new Promise((e,t)=>{if(this._isConnected)e();else if(this._isConnectingProcess&&this.openRequest[se]){const[n,r]=this.openRequest[se];this.openRequest[se]=[()=>{n(),e()},()=>{r(),t()}]}else this._isConnectingProcess=!0,this.openRequest[se]=[()=>{},()=>{}],this._connectToServer().then(()=>{e(this._checkConnection())})})}close(){this.socket&&(this._autoReconnect=!1,this.socket.onclose=()=>{},this.socket.close(),delete this.socket),this.valuesList.forEach(e=>{e._onClose()})}_readFiles(e){let t=[],n={};return e?(Object.keys(e.constructor.fields).forEach(r=>{const s=e[r];s instanceof File&&t.push(new Promise((e,t)=>{const o=a();this.openRequest[o]=[e,t],s.arrayBuffer().then(e=>{let t=new Uint8Array(e),i=Math.ceil(t.length/re);n[r]={id:o,file_name:s.name,field_name:r,content_length:s.size};for(let e=0;e<i;++e){const n=Array.from(t.slice(re*e,re*(e+1)));this.socket.send(JSON.stringify({event:"model",event_type:"upload",event_id:o,args:{chunk:n,idx:e,number_of_chunks:i,file_name:s.name,field_name:r,content_length:s.size,content_type:s.type,model_name:this.modelName,model_query:this.modelQuery}}))}}).catch(e=>{this._closeOpenRequest(o),t(e)})}))}),Promise.all(t).then(()=>n)):Promise.resolve(n)}async _onMessage(e){let t=JSON.parse(e.data);if(t.is_error)Object.hasOwn(this.openRequest,t.event_id)&&(this.openRequest[t.event_id][1](new oe(t)),this._closeOpenRequest(t.event_id)),(t.msg||t.header)&&A("pushErrorMsg",t.header||"",t.msg||""),"connect"===t.type&&(this.openRequest[se][1](new oe(t)),this._closeOpenRequest(se),this._autoReconnect=!1,this.socket.close());else{if((t.msg||t.header)&&A("pushMsg",t.header||"",t.msg||""),"connect"===t.type)this._isConnected=!0,this._isConnectingProcess=!1,this.openRequest[se][0](t),this._closeOpenRequest(se);else if(["load","list_view","named_view","detail_view"].includes(t.type)){const e=JSON.parse(t.args.data);t.args.data=await this._parseServerRes(e)}else if("on_update"===t.type||"on_create"===t.type){const e=JSON.parse(t.args.data);let n,r=await this._parseServerRes(e);n="on_create"===t.type?this.onCreate:this.onUpdate,n(r),t.args.data=r}else if("on_delete"===t.type){const e=JSON.parse(t.args.data).map(e=>le(e.id??e.pk)),n=this._removeIds(e);(this.onDelete??this.onUpdate)(n),t.args.data=n}let e=t.data?.instance;e&&(t.data.instance=JSON.parse(t.data.instance)),Object.hasOwn(this.openRequest,t.event_id)&&(this.openRequest[t.event_id][0](t),this._closeOpenRequest(t.event_id))}}noOpenRequests(){return new Promise(e=>{if(0===Object.keys(this.openRequest).length)return e();this._onNoOpenRequests.push(e)})}_closeOpenRequest(e){delete this.openRequest[e],0===Object.keys(this.openRequest).length&&(this._onNoOpenRequests.forEach(e=>e()),this._onNoOpenRequests=[])}_connectToServer(){return new Promise(e=>{const t=`${this.modelName}`+(this.modelId>0?`/${this.modelId}`:"");"https:"===window.location.protocol?this.socket=new WebSocket(`wss://${window.location.host}/sdc_ws/model/${t}`):this.socket=new WebSocket(`ws://${window.location.host}/sdc_ws/model/${t}`),this.socket.onmessage=this._onMessage.bind(this),this.socket.onclose=e=>{console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`),this._isConnected=!1;for(const t of Object.values(this.openRequest))t[1](e);this.openRequest={},this._isConnectingProcess=!1,setTimeout(()=>{this._autoReconnect&&!this._isConnected&&this.isConnected().catch(()=>{})},1e3)},this.socket.onerror=e=>{if(console.error(`Model Socket encountered error: ${e} Closing socket`),this._isConnected)try{this.socket.close()}catch(e){}},this.socket.onopen=()=>{e()}})}_checkConnection(){const e=a();return new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"connect",event_id:e,args:{model_name:this.modelName,model_query:this.modelQuery}})),this.openRequest[e]=[t,n]})}_parseServerRes(e){const t=[];for(const n of e){const e=ne(this.modelName);if(!e)throw new Error(`${this.modelName} is no SdcModel. mybe the models ar not importad.`);const r=new e({id:n.id??n.pk,...n.fields}),s=this.byId(r.id);s?(s.setValues(r),t.push(s)):(this.valuesList.push(r),r._setQuerySet(this,!0),t.push(r))}return this.valuesList.sort((e,t)=>e._id-t._id),t}}class ue{static fields={};constructor(e){this._id=null,this._forms=[],this.loaded=!1,this.formId=a(),this.modelName=e}static querySet(e=null,t=null){const{modelName:n}=new this({});return t?t.querySet(n,e):new ce(n,e)}addForm(e){const t=this._onChange.bind(this);this._forms.push(e),e&&e.on("input.formWatcher change.formWatcher","input, select, textarea",t)}_onChange(e){const{name:t}=e.target;if(this.constructor.fields[t]){try{this[`set${t}`](d(e.target))}catch{return}this._updateForm(t,e.target)}}_updateForm(e,t=null){const n=this;this._forms.forEach(r=>{r.find(`[name="${e}"]`).each(function(){this!==t&&p(this,n[e])})})}setValues(e={}){throw new Error("setValues() must be implemented by subclass")}_setQuerySet(e,t){this._querySet=new WeakRef(e),this.loaded=t}get querySet(){return this._querySet.deref()}save({formName:e="edit_form",data:t=null}={}){return this._querySet.deref().save({pk:this.id,formName:e,data:t})}create(e=null){const t=ae(e)?e.data??null:e;return this._querySet.deref().create({elem:this,data:t})}delete(){return this._querySet.deref().delete({elem:this})}load(){return this._querySet.deref().update({item:this})}update(){return this.load()}get id(){return this._id}set id(e){this._id=e}set pk(e){this.id=e}get pk(){return this._id}close(){return this._querySet.deref().close()}_onClose(){Object.keys(this.constructor.fields).filter(e=>this[`_${e}`]instanceof ce).forEach(e=>this[`_${e}`].close())}detailView({cbResolve:e=null,cbReject:t=null,templateContext:n={}}){return this._querySet.deref().detailView({pk:this.id,cbResolve:e,cbReject:t,templateContext:n})}serialize(){return Object.entries(this.constructor.fields).reduce((e,[t,n])=>{const r=this[t];if(r instanceof ce)if(n.many_to_many||n.one_to_many)e[t]=r.getIds();else{const n=r.getIds();n.length>0?e[t]=n[0]:e[t]=null}else n.is_relation&&r instanceof ue?e[t]=r.id??null:r instanceof Date?e[t]="DateField"===n.type?m(r):r.toISOString():e[t]=r;return e},{})}toJson(){const e={};for(let t in this.constructor.fields){const n=this[t];n instanceof File?e[t]=n.name:e[t]=n instanceof ue?n.id:n instanceof ce?n.getIds():n}return e}syncFormToModel(e){return this.syncForm(e)}_resolveForms(e){return e&&e.hasClass(this.formId)?e:$(`.${this.formId}`)}syncModelToForm(e){e=this._resolveForms(e);const t=this,{fields:n}=this.constructor;e.each(function(){const e=le($(this).data("model_pk"));if(le(t.id)===e)for(let e of this.elements){let{name:r}=e;r&&""!==r&&n[r]&&p(e,t[r])}})}syncForm(e){e=this._resolveForms(e);const t=this,{fields:n}=this.constructor,r={};function s(e,s){if(n[e])try{t[e]=s}catch{}r[e]=s}return e.each(function(){const e=le($(this).data("model_pk"));if(t.id===e||null===t.id&&-1===e){for(let e of this.elements)s(e.name,d(e));return t}}),r}form({cbResolve:e=null,cbReject:t=null}={}){return null===this.id||-1===this.id?this._createForm({cbReject:t,cbResolve:e}):this._editForm({cbReject:t,cbResolve:e})}_createForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"create_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}_editForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"edit_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}namedForm({formName:e,cbResolve:t=null,cbReject:n=null}){let r=$('<div class="container-fluid">');return this._querySet.deref().getForm({modelObj:this,eventType:"named_form",formName:e,$divForm:r,cbResolve:t,cbReject:n,formId:this.formId}),r}validate(e,t){const n=function(e,t){const{type:n,required:r,max_length:s,is_relation:o,many_to_many:i,one_to_many:l,many_to_one:a,one_to_one:c,related_model:u}=t;if(r&&(null==e||""===e))return"This field is required";if(null==e||""===e)return null;if((i||l||a||c)&&(!(e instanceof ce)||e.modelName!==u))return"string"==typeof e&&(e=JSON.parse(e)),(i||a)&&Array.isArray(e)&&e.some(e=>!Number.isNaN(parseInt(e)))?null:"object"!=typeof e&&Number.isNaN(parseInt(e))?"Must be object or ID":null;switch(n){case"CharField":case"TextField":if("string"!=typeof e)return"Must be a string";if(s&&e.length>s)return`Max length is ${s}`;break;case"IntegerField":case"SmallIntegerField":case"BigIntegerField":case"PositiveIntegerField":case"PositiveSmallIntegerField":case"PositiveBigIntegerField":case"AutoField":case"SmallAutoField":case"BigAutoField":if(!isFinite(parseInt(e)))return"Must be an integer";break;case"FloatField":case"DecimalField":if(!isFinite(parseFloat(e)))return"Must be a number";break;case"BooleanField":if("boolean"!=typeof e)return"Must be a boolean";break;case"DateField":case"DateTimeField":if(isNaN(Date.parse(e)))return"Must be a valid date";break;case"EmailField":if("string"!=typeof e||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))return"Invalid email";break;case"URLField":try{new URL(e)}catch{return"Invalid URL"}break;case"UUIDField":if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(e))return"Invalid UUID";break;case"JSONField":if("string"==typeof e)try{JSON.parse(e)}catch{return"Must be valid JSON"}break;case"FileField":if(!(ie.isValid(e)||e instanceof File||e instanceof ie))return"Must be a valid file";if("undefined"!=typeof File&&e instanceof File){if(t.max_size&&e.size>t.max_size)return`File too large (max ${t.max_size} bytes)`;if(t.allowed_types&&!t.allowed_types.includes(e.type))return`Invalid file type (${e.type})`}}return null}(e,t);if(n)throw new Error(n)}parseValue(e,t){const{type:n,many_to_many:r,one_to_many:s,many_to_one:o,one_to_one:i}=t;if(null===e)return null;if((r||s||o||i)&&e&&"string"==typeof e)return JSON.parse(e);switch(n){case"CharField":case"TextField":case"SlugField":case"UUIDField":case"EmailField":return`${e}`;case"IntegerField":case"SmallIntegerField":case"BigIntegerField":case"PositiveIntegerField":case"PositiveSmallIntegerField":case"PositiveBigIntegerField":case"AutoField":case"SmallAutoField":case"BigAutoField":return parseInt(e,10);case"FloatField":case"DecimalField":return parseFloat(e);case"BooleanField":return!!e;case"DateField":case"DateTimeField":return f(e);case"URLField":return new URL(e);case"FileField":if(null==e)return null;if("string"==typeof e)return null;if(ie.isValid(e))return new ie(e);if(e instanceof ie)return new ie(e);if("undefined"!=typeof File&&e instanceof File)return e;break;case"JSONField":if("object"==typeof e)return e;if("string"==typeof e)return JSON.parse(e)}return e}}let de=!1,he=!1,fe=null,me={};function pe(){return window.SERVER_CALL_VIA_WEB_SOCKET?new Promise(e=>de?e():he?void setTimeout(()=>{pe().then(()=>{e()})},200):e(ge())):Promise.resolve(!0)}function _e(){window.SERVER_CALL_VIA_WEB_SOCKET&&function(){if(de){de=!1;try{fe.close()}catch(e){}}}()}function ge(){return he=!0,new Promise(e=>{fe="https:"===window.location.protocol?new WebSocket(`wss://${window.location.host}/sdc_ws/ws/`):new WebSocket(`ws://${window.location.host}/sdc_ws/ws/`),fe.onmessage=function(e){ye(JSON.parse(e.data))},fe.onclose=function(){de&&console.error("SDC Socket closed unexpectedly"),de=!1;for(const[e,t]of Object.entries(me))t[1]({}),delete me[e];setTimeout(()=>{ge()},1e3)},fe.onerror=function(e){if(console.error("Socket encountered error: ",e.message,"Closing socket"),de)try{fe.close()}catch(e){}},fe.onopen=function(){de=!0,he=!1,e()}})}function ye(e){if(e||(e={}),e.is_error)(e.msg||e.header)&&A("pushErrorMsg",e.header||"",e.msg||""),e.id&&me[e.id]&&(me[e.id][1](e.data||null),delete me[e.id]);else if((e.msg||e.header)&&A("pushMsg",e.header||"",e.msg||""),e.type&&"sdc_recall"===e.type){const{data:t}=e;t&&"object"==typeof t&&(t.msg||t.header)&&A("pushMsg",t.header||"",t.msg||""),e.id&&me[e.id]&&(me[e.id][0](e.data),delete me[e.id])}else if(e.type&&"sdc_event"===e.type){let{event:t}=e;t&&A(t,e.payload)}else e.type&&"sdc_redirect"===e.type&&A("onNavLink",e.link)}class ve{constructor(){this._uuid=a(),this.contentUrl="",this.contentReload=!1,this.parsedContentUrl=null,this.events=[],this.load_async=!1,this._allEvents=null,this._autoRedirect=null,this._params={},this._urlParams=[],this._models=[],this._cssUrls=[],this.afterShow=()=>{console.warn("afterShow is deprecated!!")},this._mixins={},this._tagName=Object.getPrototypeOf(this)._tagName??"",this._childController={},this._parentController=null,this._onLoadDone=!1,this.$container=null,this._isMixin=!1}get params(){return this._params}set params(e){this._params=e}_runLifecycle(e,t){$e.DEBUG&&!this._isMixin&&console.debug(e,this._tagName);let n=[];if(!this._isMixin){this._isMixin=!0;for(let r in this._mixins){let s=this._mixins[r];"function"==typeof s[e]&&n.push(s[e].apply(this,t))}return Promise.all(n).then(()=>{this._isMixin=!1})}}onInit(){$e.DEBUG&&!this._isMixin&&console.debug(Array.apply(null,arguments),this._tagName)}set autoRedirect(e){this._autoRedirect=e}get autoRedirect(){return this._autoRedirect}get parentController(){return this._parentController}get childController(){return this._childController}onLoad(){return this._runLifecycle("onLoad",arguments)}willShow(){return this._runLifecycle("willShow",arguments)}onRefresh(){return this._runLifecycle("onRefresh",arguments)}onRemove(){return this._runLifecycle("onRemove",arguments),!0}noOpenModelRequests(){return Promise.all(this._models.map(e=>e.noOpenRequests()))}remove(){for(const e of this._models)e.close();const{_childController:e}=this;for(let t in e)if(Object.hasOwn(e,t))for(let n of e[t])if(!n.remove())return!1;if(!this.onRemove||this.onRemove()){T(this);const e=r(this._tagName);if(this._parentController._childController[e]){let t=this._parentController._childController[e];for(let e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)}return this.$container.remove(),!0}return!1}controller_name(){return this._tagName.replace(/-./g,e=>` ${e[1].toUpperCase()}`).replace(/^./g,e=>`${e.toUpperCase()}`)}addEvent(e,t,n){this.getEvents(),this._allEvents[e]=this._allEvents[e]||{},this._allEvents[e][t]=n}getEvents(){if(this._allEvents)return this._allEvents;let e=[];e=e.concat(this.events);for(let t in this._mixins){let n=this._mixins[t];Array.isArray(n.events)&&(e=e.concat(n.events))}return this._allEvents=_.merge({},...e)}post(e,t){return $e.post(this,e,t)}get(e,t){return $e.get(this,e,t)}submitForm(e,t,n){return $e.submitFormAndUpdateView(this,e,t,n)}serverCall(e,t){let n=this.contentUrl.match(/sdc_view\/([^/]+)/i);if(n&&!(n.length<2))return function(e,t,n,r,s){return s=function(e){return null==e?{}:"object"!=typeof e||Array.isArray(e)?{arg0:e}:e}(s),window.SERVER_CALL_VIA_WEB_SOCKET?function(e,t,n,r){let s=a();return pe().then(()=>{fe.send(JSON.stringify({event:"sdc_call",id:s,controller:t,app:e,function:n,args:r}))}),new Promise((e,t)=>{me[s]=[e,t]})}(e,t,r,s):function(e,t,n){return n={data:JSON.stringify(n),_sdc_func_name:t,_method:"sdc_server_call"},$.post({url:e,data:n,beforeSend:function(e,t){e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}}).then(e=>{const t=e._return_data;return ye(t),t}).catch(e=>{const t=e.responseJSON||{};throw t.is_error=!0,ye(t),e})}(n,r,s)}(n[1],this._tagName,this.parsedContentUrl??this.contentUrl,e,t);console.error("To use the serverCall function the contentUrl must contain sdc_view/<app>: "+this._tagName)}querySet(e,t={}){const n=new ce(e,t);return this._models.push(n),n}newModel(e,t={}){return console.warn("newModel is deprecated and will soon be removed. Please use this.querySet(modelName, modelQuery)"),this.querySet(e,t)}find(e){return this.$container.find(e)}refresh(){return $e.refresh(this.$container,this)}reload(){return $e.reloadController(this)}reconcile(e,t=null){return $e.reconcile(this,e,t)}submitModelFormDistributor(e,t){return"function"==typeof this._submitModelForm?this._submitModelForm(e,t):"function"==typeof this.submitModelForm?this.submitModelForm(e,t):this.defaultSubmitModelForm(e,t)}iterateAllChildren(){const{_childController:e}=this;let t=[];for(let n in e)if(Object.hasOwn(e,n))for(let r of e[n])t.push(r),t.push(...r.iterateAllChildren());return t}defaultSubmitModelForm(e,t){if(!this._isMixin){t.stopPropagation(),t.preventDefault();let{model:n,form_name:r}=e.data(),s=n.syncForm(e);return new Promise((t,o)=>{let i;i=null!==n.id&&n.id>=0?n.save({formName:r,data:s}):n.create({data:s}),i.then(n=>{c(e);const r=Array.isArray(n)?n[0]:n;this.submit_model_form_success&&this.submit_model_form_success(r);for(const e of this.iterateAllChildren())e.submit_model_form_success&&e.submit_model_form_success(r);t(n)}).catch(t=>{this.reconcile($(`<div class="container-fluid">${t.html}</div>`),e.find(".container-fluid").first()),this.submit_model_form_error&&this.submit_model_form_error(t);for(const e of this.iterateAllChildren())e.submit_model_form_error&&e.submit_model_form_error(t);o(t)})})}return Promise.resolve()}}const we={classname:"class"};window.sdcDom=function(e,t,...n){if(!e)return"";const r=function(e,t){let n,r=!1;if("string"==typeof e)n=$(document.createElement(e));else{const t=`this.${e.name}`;n=$(document.createElement(t)),n.data("handler",e),r=!0}return t&&Object.entries(t).forEach(([e,t])=>{if(e.startsWith("on")){const r=e.substring(2).toLowerCase();n[0].addEventListener(r,t),(n[0]._sdcListeners??=[]).push([r,t])}else we[e.toLowerCase()]&&(e=we[e.toLowerCase()]),n[0].setAttribute(e,t)}),r&&n.addClass("_bind_to_update_handler _with_handler"),n}(e,t);for(const e of n)r.append(e);return r};const be=e=>{e["url-link"]?A("onNavLink",e["url-link"]):window.location.href=e.url};let $e={CSRF_TOKEN:window.CSRF_TOKEN||"",LANGUAGE_CODE:window.LANGUAGE_CODE||"en",DEBUG:window.DEBUG||!1,VERSION:window.VERSION||"0.0",tagNames:[],Global:N,rootController:null,globalRootController:null,_isInit:!1,_origin_trigger:null,_globalControllerClasses:[],_createdGlobals:[],init_sdc:()=>{$e._isInit||($e._isInit=!0,$e._origin_trigger?_e():($e._origin_trigger=$.fn.trigger,$.fn.trigger=function(e){const t={}.hasOwnProperty.call(e,"type")?e.type:e;return w.includes(t)||(w.push(t),$(window).on(t,R)),$e._origin_trigger.call(this,e)},$e.updateJquery()),pe(),function(){const e=$(window);w.forEach(t=>{e.off(t).on(t,R)})}(),$e.rootController=$e.rootController||new ve,$e.globalRootController=$e.globalRootController||new ve),$e.tagNames=Object.keys(O);const t=N.filter(e=>!$e._createdGlobals.includes(e));$e._createdGlobals.push(...t);const n=$("<div></div>");t.forEach(e=>{const t=O[e][0];n.append(`<${t.prototype._tagName}></${t.prototype._tagName}>`)});const{refreshProcess:r}=I(null,$e.rootController);return K($e.tagNames,n,$e.globalRootController,r).then(()=>K($e.tagNames,(e||(e=$("body")),e),$e.rootController,r).then(e=>(x(r),e)))},updateJquery:()=>{$.fn.safeReplace=function(e){return $e.safeReplace($(this),e)},$.fn.safeEmpty=function(){return $e.safeEmpty($(this))},$.fn.safeRemove=function(){return $e.safeRemove($(this))}},controllerToTag:e=>n(e.name).replace(/-controller$/,""),registerGlobal:e=>{const t=$e.register(e);let n=e.prototype._tagName;return N.includes(n)||N.push(n),t},cleanCache:()=>{D={}},register:(e,t=!1)=>{let r=$e.controllerToTag(e);return!O[r]||t?(O[r]=[e,[]],e.prototype._tagName=r,{addMixin:(...e)=>{for(let t of e){let e;"string"==typeof t?e=n(t):t&&(e=$e.controllerToTag(t)),O[r][1].push(e)}}}):{addMixin:(...e)=>{}}},post:(e,t,n)=>(n||(n={}),n.CSRF_TOKEN=$e.CSRF_TOKEN,$e.ajax(e,t,n,$.post)),get:(e,t,n)=>$e.ajax(e,t,n,$.get),ajax:(e,t,n,r)=>{n||(n={}),n.VERSION=$e.VERSION,n._method=n._method||"api";const s=new Promise((o,i)=>r(t,n).then((t,n,r)=>{o(t,n,r),"redirect"===t.status?be(t):s.then(()=>{$e.refresh(e.$container)})}).catch((e,t,n)=>{301===e.status&&e.responseJSON?(e=e.responseJSON,be(e),o(e,t,n)):i(e,t,n)}));return s},submitFormAndUpdateView:(e,t,n,r)=>{let s=new FormData(t);const i=new Promise((l,a)=>{o(s,n||t.action,r||t.method).then((t,n,r)=>{l(t,n,r),"redirect"===t.status?be(t):i.then(()=>{$e.refresh(e.$container,e)})}).catch((e,t,n)=>{301===e.status?(e=e.responseJSON,be(e),l(e,t,n)):a(e,t,n)})});return i},submitForm:(e,t,n)=>{let r=new FormData(e);return new Promise((s,i)=>{o(r,t||e.action,n||e.method).then(s).catch(i)})},getController:e=>W(e),safeEmpty:e=>(e.children().each(function(e,t){let n=$(t);$e.safeRemove(n)}),e),safeReplace:(e,t)=>(t.insertBefore(e),$e.safeRemove(e)),safeRemove:e=>(e.each(function(){let e=$(this);e.data(`${U}`)&&e.data(`${U}`).remove()}),e.find(`.${M}`).each(function(){const e=$(this).data(`${U}`);e&&e.remove()}),e.remove()),reloadController:e=>function(e){if(e.contentUrl){let t=B(e);return e.contentUrl=t.url,V(e,t.args)}return new Promise(e=>{e($())})}(e).then(t=>{let n=$(t);return $e.reconcile(e,n)}),reconcile:(e,t,n=null,r=null)=>{if(!n){let n=e.$container.clone().empty();n.data(U,null),n.removeClass(M),n.append(t),t=n}n=n??e.$container;const{refreshProcess:s,isRunningProcess:o}=I(r,e);return Z(t,e,s).then(()=>{var r;return X(t,n),(r=e)._childController={},r.find(`.${M}`).each(function(){const e=$(this),t=W(e);t&&W(e.parent())===r&&S(r,t)}),o||x(s),e})},refresh:(e,t=null)=>Z(e,t)};function Re(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)"__proto__"!==r&&(e[r]=n[r])}return e}var Ce=function e(t,n){function r(e,r,s){if("undefined"!=typeof document){"number"==typeof(s=Re({},n,s)).expires&&(s.expires=new Date(Date.now()+864e5*s.expires)),s.expires&&(s.expires=s.expires.toUTCString()),e=encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var o="";for(var i in s)s[i]&&(o+="; "+i,!0!==s[i]&&(o+="="+s[i].split(";")[0]));return document.cookie=e+"="+t.write(r,e)+o}}return Object.create({set:r,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var n=document.cookie?document.cookie.split("; "):[],r={},s=0;s<n.length;s++){var o=n[s].split("="),i=o.slice(1).join("=");try{var l=decodeURIComponent(o[0]);if(l in r||(r[l]=t.read(i,l)),e===l)break}catch(e){}}return e?r[e]:r}},remove:function(e,t){r(e,"",Re({},t,{expires:-1}))},withAttributes:function(t){return e(this.converter,Re({},this.attributes,t))},withConverter:function(t){return e(Re({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(n)},converter:{value:Object.freeze(t)}})}({read:function(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}},{path:"/"});let Ne,Oe=[];function Se(){if(!jest)throw new Error("JEST is not defined");0===Oe.length&&(Ne=$.ajax.bind($),Oe.push(jest.spyOn($,"ajax")),Oe[0].mockImplementation(function(e){return Ne(e).then(e=>e).catch(e=>e)}))}const Fe=_e,ke={get_controller:async function(e,t={},n=""){Se();const r=$("body");$e.updateJquery(),r.safeEmpty();const s=$(`<${e}>${n}</${e}>`);for(const[e,n]of Object.entries(t))s.data(e,n);const o=$("<div></div>").append(s);r.append(o),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc();const i=$e.getController(s);return i.navControllerPath=[e],i},getCsrfToken:function(){return function(e){if(document.cookie&&""!==document.cookie){const t=document.cookie.split(";");for(let n=0;n<t.length;n++){const r=t[n].trim();if(r.substring(0,10)===e+"=")return decodeURIComponent(r.substring(10))}}return""}("csrftoken")},controllerFromTestHtml:async function(e,t=null){Se();const n=$("body");$e.updateJquery(),n.safeEmpty().append(e),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc();let r=$e.rootController.iterateAllChildren();if(!t)return r;const s=r[0].onRefresh,o=jest.spyOn(r[0],"onRefresh");return new Promise(e=>{o.mockImplementation(function(){o.mockRestore();const t=s.apply(r[0],arguments);return e(r),t})})},logout:()=>{Ce.remove("sessionid"),console.log("Logged out")},login:e=>{const t=globalThis.SDC_TEST_USER?.[e];return t?(Ce.set("sessionid",t),console.log(`Logged in as ${e}`),!0):(Ce.remove("sessionid"),console.warn(`Unknown test user: ${e}`),!1)}};export{ve as AbstractSDC,ue as SdcModel,ce as SdcQuerySet,T as allOff,$e as app,l as checkIfParamNumberBoolOrString,c as clearErrorsInForm,k as controllerFactory,L as on,te as registerModel,E as runControlFlowFunctions,u as setErrorsInForm,q as setEvent,Fe as socketReconnect,ke as test_utils,A as trigger};
|
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* @license
|
|
3
|
-
* Lodash <https://lodash.com/>
|
|
4
|
-
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
5
|
-
* Released under MIT license <https://lodash.com/license>
|
|
6
|
-
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
7
|
-
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
8
|
-
*/
|
|
1
|
+
/*! js-cookie v3.0.8 | MIT */
|
package/gulp/gulp.jsx
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const sass = require('gulp-sass')(require('sass'));
|
|
2
|
-
const through = require('through2');
|
|
3
2
|
const {src, dest, series, parallel} = require('gulp');
|
|
4
|
-
const gclean = require('gulp-clean');
|
|
5
3
|
const fs = require('fs');
|
|
6
4
|
const exec = require('gulp-exec');
|
|
7
5
|
const dotenv = require("dotenv");
|
|
@@ -18,52 +16,19 @@ function scss(bundle_mode = false) {
|
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* as prototype property to the controller
|
|
19
|
+
* Copies the client sources (following the linked app directories) to ./_build,
|
|
20
|
+
* which the bundle tasks use as input.
|
|
24
21
|
*
|
|
25
22
|
* @returns {*}
|
|
26
23
|
*/
|
|
27
24
|
function pre_compile_javascript() {
|
|
28
25
|
let fileExtensions = process.env.JS_CILENT_FILE_EXTENTIONS?.split(',') || ['.js', '.json'];
|
|
29
26
|
return src(fileExtensions.map((x) => `./src/**/*${x}`), {follow: true})
|
|
30
|
-
.pipe(through.obj(function (obj, enc, next) {
|
|
31
|
-
let srcFile = obj.path
|
|
32
|
-
if (!obj.isNull() && !obj.isDirectory() && obj.isBuffer() && /.js$/.test(srcFile)) {
|
|
33
|
-
let file_content = obj.contents.toString().split('\n');
|
|
34
|
-
let controller_name = null;
|
|
35
|
-
let on_init_p_name = null;
|
|
36
|
-
file_content.forEach((element) => {
|
|
37
|
-
if (!controller_name) {
|
|
38
|
-
let a = element.match(/class (.*)\s+extends\s*AbstractSDC /);
|
|
39
|
-
if (a) controller_name = a[1];
|
|
40
|
-
}
|
|
41
|
-
if (!on_init_p_name) {
|
|
42
|
-
let fnStr = element.match(/^\s*(async)?\s*onInit\s*\((.*)\)\s*\{/);
|
|
43
|
-
if (fnStr) {
|
|
44
|
-
on_init_p_name = fnStr[2].match(/(?<=^|,\s?)[^=\s,]+/g);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
if (file_content && controller_name && on_init_p_name) {
|
|
51
|
-
file_content.push(`${controller_name}.prototype._on_init_params = function() {return ["${on_init_p_name.join('", "')}"]; };`);
|
|
52
|
-
obj.contents = Buffer.from(file_content.join('\n'));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
next(null, obj);
|
|
57
|
-
}))
|
|
58
27
|
.pipe(dest('./_build'));
|
|
59
28
|
}
|
|
60
29
|
|
|
61
30
|
function clean(done) {
|
|
62
|
-
|
|
63
|
-
return src('./_build').pipe(gclean());
|
|
64
|
-
} else {
|
|
65
|
-
done()
|
|
66
|
-
}
|
|
31
|
+
fs.rm('./_build', {recursive: true, force: true}, done);
|
|
67
32
|
}
|
|
68
33
|
|
|
69
34
|
function link_files(cb) {
|
|
@@ -100,10 +65,14 @@ function link_files(cb) {
|
|
|
100
65
|
}
|
|
101
66
|
|
|
102
67
|
|
|
68
|
+
// File events that trigger a rebuild in the develop watchers.
|
|
69
|
+
const WATCH_EVENTS = ['add', 'change', 'unlink'];
|
|
70
|
+
|
|
103
71
|
exports.sdc_watch_scss = function () {
|
|
104
72
|
const watcher = gulp.watch('./src/**/*.scss', {followSymlinks: true});
|
|
105
|
-
watcher.on('
|
|
106
|
-
|
|
73
|
+
watcher.on('all', (event, a) => {
|
|
74
|
+
if (!WATCH_EVENTS.includes(event)) return;
|
|
75
|
+
console.log(`${a}: ${event}! SCSS is recompiling...`);
|
|
107
76
|
scss()().on('end', () => {
|
|
108
77
|
console.log(`... recompiling done!`);
|
|
109
78
|
});
|
|
@@ -126,8 +95,9 @@ exports.sdc_watch_webpack_factory = (webpack_task, cb) => {
|
|
|
126
95
|
usePolling: false, // optional
|
|
127
96
|
ignored: /node_modules/,
|
|
128
97
|
})
|
|
129
|
-
watcher.on('
|
|
130
|
-
|
|
98
|
+
watcher.on('all', (event, a) => {
|
|
99
|
+
if (!WATCH_EVENTS.includes(event)) return;
|
|
100
|
+
console.log(`${a}: ${event}! javascript is recompiling...`);
|
|
131
101
|
webpack_series_factory(webpack_task)();
|
|
132
102
|
cb && cb();
|
|
133
103
|
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdc_client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.159.0",
|
|
4
4
|
"description": "Simple Dom Control",
|
|
5
5
|
"main": "dist/ugly.index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"src",
|
|
9
|
+
"gulp",
|
|
10
|
+
"README.md",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
6
13
|
"type": "module",
|
|
14
|
+
"packageManager": "yarn@4.18.0",
|
|
7
15
|
"scripts": {
|
|
8
|
-
"build": "gulp development
|
|
9
|
-
"test": "gulp development
|
|
16
|
+
"build": "gulp development && gulp build",
|
|
17
|
+
"test": "gulp development && NODE_OPTIONS=--experimental-vm-modules jest",
|
|
10
18
|
"format": "prettier --write \"src/**/*.{js,jsx,scss,css,html,json}\"",
|
|
11
19
|
"format:js": "eslint --fix \"src/**/*.js\"",
|
|
12
20
|
"lint:js": "eslint \"src/**/*.js\""
|
|
@@ -26,43 +34,43 @@
|
|
|
26
34
|
"author": "Martin Starman",
|
|
27
35
|
"license": "MIT",
|
|
28
36
|
"devDependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@babel/eslint-parser": "^7.27.1",
|
|
31
|
-
"@babel/plugin-transform-runtime": "^7.26.10",
|
|
32
|
-
"@babel/preset-env": "^7.26.9",
|
|
33
|
-
"@babel/preset-react": "^7.26.3",
|
|
34
|
-
"@babel/register": "^7.25.9",
|
|
35
|
-
"@eslint/js": "^9.19.0",
|
|
36
|
-
"babel-loader": "^10.0.0",
|
|
37
|
+
"@eslint/js": "^10.0.1",
|
|
37
38
|
"baseline-browser-mapping": "^2.9.19",
|
|
38
|
-
"
|
|
39
|
-
"eslint": "^9.19.0",
|
|
40
|
-
"eslint-plugin-no-relative-import-paths": "^1.6.1",
|
|
41
|
-
"eslint-plugin-react": "^7.37.5",
|
|
39
|
+
"eslint": "^10.8.1",
|
|
42
40
|
"glob-parent": "^6.0.2",
|
|
43
41
|
"globals": "^15.14.0",
|
|
44
42
|
"gulp": "^5.0.1",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"jest-environment-jsdom": "^29.7.0",
|
|
43
|
+
"jest": "^30.4.2",
|
|
44
|
+
"jest-environment-jsdom": "^30.4.1",
|
|
45
|
+
"jquery": "^3.7.1",
|
|
46
|
+
"lodash": "4.17.23",
|
|
50
47
|
"micromatch": "^4.0.8",
|
|
51
48
|
"prettier": "^3.8.1",
|
|
52
|
-
"
|
|
53
|
-
"through2": "^4.0.2",
|
|
54
|
-
"vinyl-named": "^1.1.0",
|
|
55
|
-
"webpack": "^5.104.1",
|
|
56
|
-
"webpack-stream": "^7.0.0"
|
|
49
|
+
"webpack": "^5.104.1"
|
|
57
50
|
},
|
|
58
51
|
"overrides": {
|
|
59
|
-
"glob
|
|
52
|
+
"glob": "^13.0.6",
|
|
53
|
+
"glob-parent": "$glob-parent",
|
|
54
|
+
"jsdom": "^29.1.1",
|
|
55
|
+
"test-exclude": "^8.0.0"
|
|
56
|
+
},
|
|
57
|
+
"resolutions": {
|
|
58
|
+
"glob": "^13.0.6",
|
|
59
|
+
"glob-parent": "^6.0.2",
|
|
60
|
+
"jsdom": "^29.1.1",
|
|
61
|
+
"test-exclude": "^8.0.0"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
64
|
+
"dotenv": "^16.4.7",
|
|
65
|
+
"gulp-exec": "^5.0.0",
|
|
66
|
+
"gulp-sass": "^6.0.1",
|
|
67
|
+
"js-cookie": "^3.0.8",
|
|
68
|
+
"sass": "^1.85.1",
|
|
69
|
+
"through2": "^4.0.2"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"gulp": "^5.0.0",
|
|
73
|
+
"jquery": "^3.7.0",
|
|
74
|
+
"lodash": "^4.17.21"
|
|
67
75
|
}
|
|
68
76
|
}
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {app} from "./simpleDomControl/sdc_main.js";
|
|
2
|
-
import {AbstractSDC} from "./simpleDomControl/AbstractSDC.js";
|
|
3
|
-
import SdcModel, {SdcQuerySet} from "./simpleDomControl/sdc_model.js";
|
|
4
|
-
import {registerModel} from "./simpleDomControl/sdc_socket.js";
|
|
1
|
+
import { app } from "./simpleDomControl/sdc_main.js";
|
|
2
|
+
import { AbstractSDC } from "./simpleDomControl/AbstractSDC.js";
|
|
3
|
+
import SdcModel, { SdcQuerySet } from "./simpleDomControl/sdc_model.js";
|
|
4
|
+
import { registerModel } from "./simpleDomControl/sdc_socket.js";
|
|
5
|
+
import Cookies from "js-cookie";
|
|
5
6
|
import {
|
|
6
7
|
on,
|
|
7
8
|
trigger,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
controllerFactory,
|
|
19
20
|
runControlFlowFunctions,
|
|
20
21
|
} from "./simpleDomControl/sdc_controller.js";
|
|
21
|
-
import {close} from "./simpleDomControl/sdc_server_call.js";
|
|
22
|
+
import { close } from "./simpleDomControl/sdc_server_call.js";
|
|
22
23
|
import {
|
|
23
24
|
get_controller,
|
|
24
25
|
getCsrfToken,
|
|
@@ -26,7 +27,26 @@ import {
|
|
|
26
27
|
} from "./simpleDomControl/sdc_test_utils.js";
|
|
27
28
|
|
|
28
29
|
const socketReconnect = close;
|
|
29
|
-
const test_utils = {
|
|
30
|
+
const test_utils = {
|
|
31
|
+
get_controller,
|
|
32
|
+
getCsrfToken,
|
|
33
|
+
controllerFromTestHtml,
|
|
34
|
+
logout: () => {
|
|
35
|
+
Cookies.remove("sessionid");
|
|
36
|
+
console.log("Logged out");
|
|
37
|
+
},
|
|
38
|
+
login: (user) => {
|
|
39
|
+
const sessionId = globalThis.SDC_TEST_USER?.[user];
|
|
40
|
+
if (!sessionId) {
|
|
41
|
+
Cookies.remove("sessionid");
|
|
42
|
+
console.warn(`Unknown test user: ${user}`);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
Cookies.set("sessionid", sessionId);
|
|
46
|
+
console.log(`Logged in as ${user}`);
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
30
50
|
|
|
31
51
|
export {
|
|
32
52
|
app,
|
|
@@ -44,5 +64,5 @@ export {
|
|
|
44
64
|
test_utils,
|
|
45
65
|
SdcModel,
|
|
46
66
|
SdcQuerySet,
|
|
47
|
-
registerModel
|
|
67
|
+
registerModel,
|
|
48
68
|
};
|
|
@@ -17,8 +17,8 @@ export class AbstractSDC {
|
|
|
17
17
|
this.parsedContentUrl = null;
|
|
18
18
|
this.events = [];
|
|
19
19
|
this.load_async = false;
|
|
20
|
-
this._isEventsSet = false;
|
|
21
20
|
this._allEvents = null;
|
|
21
|
+
this._autoRedirect = null;
|
|
22
22
|
this._params = {};
|
|
23
23
|
|
|
24
24
|
this._urlParams = [];
|
|
@@ -106,6 +106,8 @@ export class AbstractSDC {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
|
+
* @deprecated Not called by the runtime since 0.158.7. Read the data-*
|
|
110
|
+
* attributes from ``this.params`` in ``onLoad()`` instead.
|
|
109
111
|
*
|
|
110
112
|
* @return {Promise<*>|*}
|
|
111
113
|
*/
|
|
@@ -115,6 +117,14 @@ export class AbstractSDC {
|
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
|
|
120
|
+
set autoRedirect(url){
|
|
121
|
+
this._autoRedirect = url;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get autoRedirect() {
|
|
125
|
+
return this._autoRedirect;
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
get parentController() {
|
|
119
129
|
return this._parentController;
|
|
120
130
|
}
|
|
@@ -148,9 +158,9 @@ export class AbstractSDC {
|
|
|
148
158
|
for (const model of this._models) {
|
|
149
159
|
model.close();
|
|
150
160
|
}
|
|
151
|
-
|
|
161
|
+
const { _childController } = this;
|
|
152
162
|
for (let i in _childController) {
|
|
153
|
-
if (
|
|
163
|
+
if (Object.hasOwn(_childController, i)) {
|
|
154
164
|
for (let cc of _childController[i]) {
|
|
155
165
|
if (!cc.remove()) {
|
|
156
166
|
return false;
|
|
@@ -172,7 +182,6 @@ export class AbstractSDC {
|
|
|
172
182
|
}
|
|
173
183
|
|
|
174
184
|
this.$container.remove();
|
|
175
|
-
delete this;
|
|
176
185
|
return true;
|
|
177
186
|
}
|
|
178
187
|
|
|
@@ -200,7 +209,9 @@ export class AbstractSDC {
|
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
|
|
203
|
-
|
|
212
|
+
// Merge into a new object: the event maps of the controller and its mixins
|
|
213
|
+
// may be shared between instances and must not be changed.
|
|
214
|
+
return (this._allEvents = _.merge({}, ...allEvents));
|
|
204
215
|
}
|
|
205
216
|
|
|
206
217
|
post(url, args) {
|
|
@@ -220,8 +231,8 @@ export class AbstractSDC {
|
|
|
220
231
|
let app = this.contentUrl.match(re);
|
|
221
232
|
if (!app || app.length < 2) {
|
|
222
233
|
console.error(
|
|
223
|
-
"To use the serverCall function the contentUrl must
|
|
224
|
-
this.
|
|
234
|
+
"To use the serverCall function the contentUrl must contain sdc_view/<app>: " +
|
|
235
|
+
this._tagName,
|
|
225
236
|
);
|
|
226
237
|
return;
|
|
227
238
|
}
|
|
@@ -283,10 +294,10 @@ export class AbstractSDC {
|
|
|
283
294
|
}
|
|
284
295
|
|
|
285
296
|
iterateAllChildren() {
|
|
286
|
-
|
|
297
|
+
const { _childController } = this;
|
|
287
298
|
let res = [];
|
|
288
299
|
for (let i in _childController) {
|
|
289
|
-
if (
|
|
300
|
+
if (Object.hasOwn(_childController, i)) {
|
|
290
301
|
for (let cc of _childController[i]) {
|
|
291
302
|
res.push(cc);
|
|
292
303
|
res.push(...cc.iterateAllChildren());
|
|
@@ -316,11 +327,13 @@ export class AbstractSDC {
|
|
|
316
327
|
prom
|
|
317
328
|
.then((res) => {
|
|
318
329
|
clearErrorsInForm($form);
|
|
330
|
+
// save() resolves with a list of responses, create() with one response.
|
|
331
|
+
const response = Array.isArray(res) ? res[0] : res;
|
|
319
332
|
this.submit_model_form_success &&
|
|
320
|
-
this.submit_model_form_success(
|
|
333
|
+
this.submit_model_form_success(response);
|
|
321
334
|
for (const controller of this.iterateAllChildren()) {
|
|
322
335
|
controller.submit_model_form_success &&
|
|
323
|
-
controller.submit_model_form_success(
|
|
336
|
+
controller.submit_model_form_success(response);
|
|
324
337
|
}
|
|
325
338
|
|
|
326
339
|
resolve(res);
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
|
|
14
14
|
import { runOnInitWithParameter } from "./sdc_params.js";
|
|
15
15
|
import { setControllerEvents } from "./sdc_dom_events.js";
|
|
16
|
-
import
|
|
16
|
+
import "./sdc_main.js";
|
|
17
17
|
|
|
18
18
|
export let Global = [];
|
|
19
19
|
export let controllerList = {};
|
|
@@ -74,7 +74,8 @@ export function resetChildren(parentController) {
|
|
|
74
74
|
parentController.find(`.${CONTROLLER_CLASS}`).each(function () {
|
|
75
75
|
const $this = $(this);
|
|
76
76
|
const cController = getController($this);
|
|
77
|
-
|
|
77
|
+
// Direct children only: the closest controller around the child element is the parent.
|
|
78
|
+
if (cController && getController($this.parent()) === parentController) {
|
|
78
79
|
setParentController(parentController, cController);
|
|
79
80
|
}
|
|
80
81
|
});
|
|
@@ -229,7 +230,10 @@ export function runControlFlowFunctions(controller, process) {
|
|
|
229
230
|
return runRefresh(controller, process);
|
|
230
231
|
})
|
|
231
232
|
.catch(function ($html) {
|
|
232
|
-
|
|
233
|
+
if (typeof $html === 'string' || $html instanceof $) {
|
|
234
|
+
return runControllerFillContent(controller, $html);
|
|
235
|
+
}
|
|
236
|
+
throw $html;
|
|
233
237
|
});
|
|
234
238
|
|
|
235
239
|
if (controller.load_async) {
|
|
@@ -251,7 +255,6 @@ export function runRefresh(controller, process) {
|
|
|
251
255
|
function getParentList(controller) {
|
|
252
256
|
let controllerList = [];
|
|
253
257
|
while (controller) {
|
|
254
|
-
controller._isEventsSet = false;
|
|
255
258
|
controllerList.unshift(controller);
|
|
256
259
|
controller = controller._parentController;
|
|
257
260
|
}
|