@combos-fun/plugin-development-tool 0.0.23 → 0.0.25
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/agent-skill.md +31 -0
- package/dist/plugin-development-tool.cjs.js +123 -4
- package/dist/plugin-development-tool.cjs.js.map +1 -1
- package/dist/plugin-development-tool.cjs.prod.js +1 -1
- package/dist/plugin-development-tool.d.ts +36 -2
- package/dist/plugin-development-tool.esm.js +116 -5
- package/dist/plugin-development-tool.esm.js.map +1 -1
- package/package.json +11 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:set-success",a="combos-development-tool:refresh",d="combos-development-tool:gameobject-selected",h="combos-development-tool:apply-property",c="combos-development-tool:set-paused",l="combos-development-tool:set-muted",u="combos-development-tool:state-changed";class p extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const m=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),f={Graphics:new Set(["graphics"]),Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function g(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>g(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=g(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function y(e){const t={},n=f[e.name];for(const o of Object.keys(e)){if(m.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=g(s);void 0!==i&&(t[o]=i)}return t}function w(e){const t=e.getComponent(p),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function b(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:y(e)}));return{id:e.id,name:e.name,components:t,source:w(e)}}function O(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const E=new Set(["position","size","origin","anchor","scale","skew"]);function S(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const v={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=S(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&E.has(n[0])){const t=n[0],s=n[1],r=S(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=S(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function G(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=v[t];return!!i?.(e,s,n,o)||O(e,t,n,o)}const P="__combosDevelopmentToolOutline";let C=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.disabledGameEventGoIds=new Set,this.pickEvents=new Set,this.needsRescan=!1,this.lastOutlineBounds=null,this.mutedWithoutSoundSystem=!1,this.onWindowSet=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowSetPaused=e=>{const t=e.detail;t&&"boolean"==typeof t.paused&&this.setPaused(t.paused)},this.onWindowSetMuted=e=>{const t=e.detail;t&&"boolean"==typeof t.muted&&this.setMuted(t.muted)},this.onWindowMessage=e=>{const t=e.data;t&&"object"==typeof t&&(t.type===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===c&&"boolean"==typeof t.paused?this.setPaused(t.paused):t.type===l&&"boolean"==typeof t.muted?this.setMuted(t.muted):t.type===a?this.requestSceneRescan():t.type===h&&this.handleApplyProperty(t))},this.onGameSet=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onGameSetPaused=e=>{e&&"boolean"==typeof e.paused&&this.setPaused(e.paused)},this.onGameSetMuted=e=>{e&&"boolean"==typeof e.muted&&this.setMuted(e.muted)},this.onWindowRefresh=()=>{this.requestSceneRescan()}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*","undefined"!=typeof window&&(window.addEventListener(i,this.onWindowSet),window.addEventListener(c,this.onWindowSetPaused),window.addEventListener(l,this.onWindowSetMuted),window.addEventListener(a,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(c,this.onGameSetPaused),this.game.on(l,this.onGameSetMuted),this.game.on(a,this.onGameRefresh),this.enabled&&(this.needsRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(c,this.onWindowSetPaused),window.removeEventListener(l,this.onWindowSetMuted),window.removeEventListener(a,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(c,this.onGameSetPaused),this.game.off(l,this.onGameSetMuted),this.game.off(a,this.onGameRefresh),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?this.needsRescan=!0:(this.clearSelection(),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}get isPaused(){return!this.game.playing}get isMuted(){const e=this.getSoundSystem();return e?e.muted:this.mutedWithoutSoundSystem}setPaused(e){e?this.game.playing&&this.game.pause():this.game.playing||this.game.resume(),this.postStateChanged()}setMuted(e){const t=this.getSoundSystem();t?t.muted=e:this.mutedWithoutSoundSystem=e,this.postStateChanged()}update(e){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.attachEditMode(),this.postSetSuccess(!0));for(const e of[...this.tapOwners.values()])e.destroyed&&this.releasePick(e);this.enabled&&this.selected&&this.outlineGo&&this.updateSelectionOutline()}componentChanged(e){if(!this.enabled)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?(this.stripGameEvent(o),this.ensurePick(o)):n===t.OBSERVER_TYPE.REMOVE&&(this.releasePick(o),this.selected===o&&this.clearSelection()))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0)}attachEditMode(){this.detachAllPicks();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)this.isIgnoredPickGo(t)||this.stripGameEvent(t);for(const t of e)this.isIgnoredPickGo(t)||t.getComponent(p)&&this.ensurePick(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}isIgnoredPickGo(e){return e.name===P||e===this.outlineGo}stripGameEvent(e){if(this.disabledGameEventGoIds.has(e.id))return;if(!e.getComponent(s.Event))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!1,this.disabledGameEventGoIds.add(e.id)}catch{}}restoreDisabledGameEvents(){for(const e of[...this.disabledGameEventGoIds]){const t=this.findGameObjectById(e);if(!t||t.destroyed){this.disabledGameEventGoIds.delete(e);continue}const n=this.getRendererContainer(t);if(n)try{n.interactive=!0}catch{}this.disabledGameEventGoIds.delete(e)}}detachAllPicks(){for(const e of[...this.tapOwners.values()])this.releasePick(e)}ensurePick(e){if(this.tapHandlers.has(e.id))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!0}catch{}let n=e.getComponent(s.Event);n||(n=e.addComponent(this.createPickEvent(e)),this.pickEvents.add(e.id));const o=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,o),this.tapOwners.set(e.id,e),n.on("tap",o)}createPickEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveOwnGraphicsLocalBounds(e);if(t)return t;const n=this.resolveContainerLocalBounds(e);if(n)return n}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveOwnGraphicsLocalBounds(e){const t=e.getComponent(o.Graphics);if(!t?.graphics)return null;try{const e=t.graphics.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;const n=this.getOutlineContainerIfChildOf(e);let o=!1;n?.parent===t&&(t.removeChild(n),o=!0);try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}finally{o&&n&&t.addChild(n)}return null}getOutlineContainerIfChildOf(e){return this.outlineGo&&this.outlineGo.parent===e?this.getRendererContainer(this.outlineGo):null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releasePick(e){const t=this.tapHandlers.get(e.id);if(!t)return;const n=e.getComponent(s.Event);if(n?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.pickEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.pickEvents.delete(e.id)}}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}postStateChanged(){const e={paused:this.isPaused,muted:this.isMuted},t={type:u,...e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(u,e)}getSoundSystem(){const e=this.game.getSystem("SoundSystem");return e&&"object"==typeof e&&"muted"in e&&"boolean"==typeof e.muted?e:null}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(P,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo),this.invalidateOutlineBounds(),this.updateSelectionOutline();const n=b(e),o={type:d,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=w(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;G(i,t,n,e.value)&&this.selected?.id===i.id&&(this.invalidateOutlineBounds(),this.updateSelectionOutline(),this.postSnapshotUpdate(i))}postSnapshotUpdate(e){const t=b(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:d,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelection(){this.selected=null,this.invalidateOutlineBounds(),this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}updateSelectionOutline(){if(!this.enabled||!this.selected||!this.outlineGo)return;const e=this.outlineGo.getComponent(o.Graphics);if(!e?.graphics)return;const t=this.resolvePickBounds(this.selected);if(this.lastOutlineBounds&&this.pickBoundsEqual(this.lastOutlineBounds,t))return;this.lastOutlineBounds=t;const n=e.graphics;n.clear(),n.rect(t.x,t.y,t.width,t.height),n.stroke({width:4,color:5636010,alpha:1})}invalidateOutlineBounds(){this.lastOutlineBounds=null}pickBoundsEqual(e,t){const n=.01;return Math.abs(e.x-t.x)<n&&Math.abs(e.y-t.y)<n&&Math.abs(e.width-t.width)<n&&Math.abs(e.height-t.height)<n}};C=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],C);var M=C;Object.assign(M,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.22"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=h,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=d,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=a,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_MUTED=l,exports.COMBOS_DEVELOPMENT_TOOL_SET_PAUSED=c,exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS=r,exports.COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED=u,exports.CombosDevelopmentToolSystem=M,exports.CombosDevelopmentToolTarget=p,exports.applyPropertyValue=O,exports.applyPropertyWithHooks=G,exports.buildGameObjectSnapshot=b,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=w;
|
|
1
|
+
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:set-success",a="combos-development-tool:refresh",d="combos-development-tool:gameobject-selected",c="combos-development-tool:clear-selection",l="combos-development-tool:gameobject-deselected",h="combos-development-tool:apply-property",u="combos-development-tool:set-paused",p="combos-development-tool:set-muted",m="combos-development-tool:state-changed";class f extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const g=["knoffice.tech","converge.ai"];function y(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let n;try{n=new URL(e)}catch{return!1}const o=e.toLowerCase(),s=n.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(o===t.toLowerCase())return!0;continue}const n=t.toLowerCase().replace(/^\./,"");if(s===n||s.endsWith(`.${n}`))return!0}return!1}function w(e){if(!e?.length)return[...g];if(e.includes("*"))return["*"];const t=new Set,n=[];for(const o of[...g,...e]){const e=o.trim();e&&!t.has(e)&&(t.add(e),n.push(e))}return n}const O=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),b={Graphics:new Set(["graphics"]),Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function E(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>E(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=E(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function S(e){const t={},n=b[e.name];for(const o of Object.keys(e)){if(O.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=E(s);void 0!==i&&(t[o]=i)}return t}function v(e){const t=e.getComponent(f),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function G(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:S(e)}));return{id:e.id,name:e.name,components:t,source:v(e)}}function C(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const M=new Set(["position","size","origin","anchor","scale","skew"]);function P(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const T={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=P(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&M.has(n[0])){const t=n[0],s=n[1],r=P(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=P(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function _(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=T[t];return!!i?.(e,s,n,o)||C(e,t,n,o)}function L(e){return{type:l,reason:e}}function B(e){return e}function x(e){return!(!e||"object"!=typeof e)&&e.type===c}const D="__combosDevelopmentToolOutline";let R=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.allowedMessageOrigins=w(),this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.disabledGameEventGoIds=new Set,this.pickEvents=new Set,this.needsRescan=!1,this.lastOutlineBounds=null,this.mutedWithoutSoundSystem=!1,this.onWindowSet=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowSetPaused=e=>{const t=e.detail;t&&"boolean"==typeof t.paused&&this.setPaused(t.paused)},this.onWindowSetMuted=e=>{const t=e.detail;t&&"boolean"==typeof t.muted&&this.setMuted(t.muted)},this.onWindowMessage=e=>{if(!y(e.origin,this.allowedMessageOrigins))return;const t=e.data;t&&"object"==typeof t&&(t.type===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===u&&"boolean"==typeof t.paused?this.setPaused(t.paused):t.type===p&&"boolean"==typeof t.muted?this.setMuted(t.muted):t.type===a?this.requestSceneRescan():x(t)?this.clearSelectionAndNotify("parent-request"):t.type===h&&this.handleApplyProperty(t))},this.onGameSet=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onGameSetPaused=e=>{e&&"boolean"==typeof e.paused&&this.setPaused(e.paused)},this.onGameSetMuted=e=>{e&&"boolean"==typeof e.muted&&this.setMuted(e.muted)},this.onWindowRefresh=()=>{this.requestSceneRescan()}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*",this.allowedMessageOrigins=w(e?.allowedMessageOrigins),"undefined"!=typeof window&&(window.addEventListener(i,this.onWindowSet),window.addEventListener(u,this.onWindowSetPaused),window.addEventListener(p,this.onWindowSetMuted),window.addEventListener(a,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(u,this.onGameSetPaused),this.game.on(p,this.onGameSetMuted),this.game.on(a,this.onGameRefresh),this.enabled&&(this.needsRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(u,this.onWindowSetPaused),window.removeEventListener(p,this.onWindowSetMuted),window.removeEventListener(a,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(u,this.onGameSetPaused),this.game.off(p,this.onGameSetMuted),this.game.off(a,this.onGameRefresh),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.clearSelectionAndNotify("pick-disabled")}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?this.needsRescan=!0:(this.clearSelectionAndNotify("pick-disabled"),this.detachAllPicks(),this.restoreDisabledGameEvents(),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}get isPaused(){return!this.game.playing}get isMuted(){const e=this.getSoundSystem();return e?e.muted:this.mutedWithoutSoundSystem}setPaused(e){e?this.game.playing&&this.game.pause():this.game.playing||this.game.resume(),this.postStateChanged()}setMuted(e){const t=this.getSoundSystem();t?t.muted=e:this.mutedWithoutSoundSystem=e,this.postStateChanged()}update(e){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.attachEditMode(),this.postSetSuccess(!0));for(const e of[...this.tapOwners.values()])e.destroyed&&this.releasePick(e);this.enabled&&this.selected&&this.outlineGo&&this.updateSelectionOutline()}componentChanged(e){if(!this.enabled)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?(this.stripGameEvent(o),this.ensurePick(o)):n===t.OBSERVER_TYPE.REMOVE&&(this.releasePick(o),this.selected===o&&this.clearSelectionAndNotify("target-removed")))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0)}attachEditMode(){this.detachAllPicks();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)this.isIgnoredPickGo(t)||this.stripGameEvent(t);for(const t of e)this.isIgnoredPickGo(t)||t.getComponent(f)&&this.ensurePick(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}isIgnoredPickGo(e){return e.name===D||e===this.outlineGo}stripGameEvent(e){if(this.disabledGameEventGoIds.has(e.id))return;if(!e.getComponent(s.Event))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!1,this.disabledGameEventGoIds.add(e.id)}catch{}}restoreDisabledGameEvents(){for(const e of[...this.disabledGameEventGoIds]){const t=this.findGameObjectById(e);if(!t||t.destroyed){this.disabledGameEventGoIds.delete(e);continue}const n=this.getRendererContainer(t);if(n)try{n.interactive=!0}catch{}this.disabledGameEventGoIds.delete(e)}}detachAllPicks(){for(const e of[...this.tapOwners.values()])this.releasePick(e)}ensurePick(e){if(this.tapHandlers.has(e.id))return;const t=this.getRendererContainer(e);if(t)try{t.interactive=!0}catch{}let n=e.getComponent(s.Event);n||(n=e.addComponent(this.createPickEvent(e)),this.pickEvents.add(e.id));const o=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,o),this.tapOwners.set(e.id,e),n.on("tap",o)}createPickEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveOwnGraphicsLocalBounds(e);if(t)return t;const n=this.resolveContainerLocalBounds(e);if(n)return n}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveOwnGraphicsLocalBounds(e){const t=e.getComponent(o.Graphics);if(!t?.graphics)return null;try{const e=t.graphics.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;const n=this.getOutlineContainerIfChildOf(e);let o=!1;n?.parent===t&&(t.removeChild(n),o=!0);try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}finally{o&&n&&t.addChild(n)}return null}getOutlineContainerIfChildOf(e){return this.outlineGo&&this.outlineGo.parent===e?this.getRendererContainer(this.outlineGo):null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releasePick(e){const t=this.tapHandlers.get(e.id);if(!t)return;const n=e.getComponent(s.Event);if(n?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.pickEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.pickEvents.delete(e.id)}}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}postStateChanged(){const e={paused:this.isPaused,muted:this.isMuted},t={type:m,...e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(m,e)}getSoundSystem(){const e=this.game.getSystem("SoundSystem");return e&&"object"==typeof e&&"muted"in e&&"boolean"==typeof e.muted?e:null}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(D,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo),this.invalidateOutlineBounds(),this.updateSelectionOutline();const n=G(e),o={type:d,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=v(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;_(i,t,n,e.value)&&this.selected?.id===i.id&&(this.invalidateOutlineBounds(),this.updateSelectionOutline(),this.postSnapshotUpdate(i))}postSnapshotUpdate(e){const t=G(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:d,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelectionAndNotify(e){const t=null!=this.selected;this.clearSelection(),t&&this.postGameObjectDeselected(e)}postGameObjectDeselected(e){const t=L(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(t.type,{reason:e})}clearSelection(){this.selected=null,this.invalidateOutlineBounds(),this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}updateSelectionOutline(){if(!this.enabled||!this.selected||!this.outlineGo)return;const e=this.outlineGo.getComponent(o.Graphics);if(!e?.graphics)return;const t=this.resolvePickBounds(this.selected);if(this.lastOutlineBounds&&this.pickBoundsEqual(this.lastOutlineBounds,t))return;this.lastOutlineBounds=t;const n=e.graphics;n.clear(),n.rect(t.x,t.y,t.width,t.height),n.stroke({width:4,color:5636010,alpha:1})}invalidateOutlineBounds(){this.lastOutlineBounds=null}pickBoundsEqual(e,t){const n=.01;return Math.abs(e.x-t.x)<n&&Math.abs(e.y-t.y)<n&&Math.abs(e.width-t.width)<n&&Math.abs(e.height-t.height)<n}};R=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],R);var j=R;Object.assign(j,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.25"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=h,exports.COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION=c,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED=l,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=d,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=a,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_MUTED=p,exports.COMBOS_DEVELOPMENT_TOOL_SET_PAUSED=u,exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS=r,exports.COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED=m,exports.CombosDevelopmentToolSystem=j,exports.CombosDevelopmentToolTarget=f,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=g,exports.applyPropertyValue=C,exports.applyPropertyWithHooks=_,exports.buildGameObjectDeselectedPayload=L,exports.buildGameObjectSnapshot=G,exports.isAllowedMessageOrigin=y,exports.isClearSelectionMessage=x,exports.mergeAllowedMessageOrigins=w,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=v,exports.shouldNotifyGameObjectDeselected=B;
|
|
@@ -8,6 +8,10 @@ declare const COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS: "combos-development-tool:set-
|
|
|
8
8
|
declare const COMBOS_DEVELOPMENT_TOOL_REFRESH: "combos-development-tool:refresh";
|
|
9
9
|
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
10
10
|
declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED: "combos-development-tool:gameobject-selected";
|
|
11
|
+
/** Parent → iframe: clear the current in-canvas selection outline. */
|
|
12
|
+
declare const COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION: "combos-development-tool:clear-selection";
|
|
13
|
+
/** Emitted to `window.parent` when the current selection is cleared. */
|
|
14
|
+
declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED: "combos-development-tool:gameobject-deselected";
|
|
11
15
|
/** Parent → iframe: apply a value to a component field (live preview). */
|
|
12
16
|
declare const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY: "combos-development-tool:apply-property";
|
|
13
17
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
@@ -19,6 +23,20 @@ declare const COMBOS_DEVELOPMENT_TOOL_SET_MUTED: "combos-development-tool:set-mu
|
|
|
19
23
|
/** iframe → parent (and `game.emit`): current pause/mute snapshot after a successful change. */
|
|
20
24
|
declare const COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED: "combos-development-tool:state-changed";
|
|
21
25
|
|
|
26
|
+
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
27
|
+
declare const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES: readonly ["knoffice.tech", "converge.ai"];
|
|
28
|
+
/**
|
|
29
|
+
* Returns whether `origin` is allowed by `allowed`.
|
|
30
|
+
*
|
|
31
|
+
* Each entry in `allowed` is either:
|
|
32
|
+
* - a **host suffix** (e.g. `knoffice.tech`) — matches that host and `*.knoffice.tech`;
|
|
33
|
+
* - a **full origin** (e.g. `https://creator.knoffice.tech`) — exact match;
|
|
34
|
+
* - `'*'` — accept any origin (escape hatch).
|
|
35
|
+
*/
|
|
36
|
+
declare function isAllowedMessageOrigin(origin: string, allowed: readonly string[]): boolean;
|
|
37
|
+
/** Defaults plus any extra entries (deduped). `['*']` alone accepts any origin. */
|
|
38
|
+
declare function mergeAllowedMessageOrigins(extra?: string[]): string[];
|
|
39
|
+
|
|
22
40
|
interface CombosDevelopmentToolTargetParams extends ComponentParams {
|
|
23
41
|
/** Extra JSON-serializable fields included in postMessage to parent. */
|
|
24
42
|
payload?: Record<string, unknown>;
|
|
@@ -37,6 +55,11 @@ declare class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToo
|
|
|
37
55
|
interface CombosDevelopmentToolSystemParams {
|
|
38
56
|
/** postMessage `targetOrigin` when notifying parent (default `'*'`). */
|
|
39
57
|
postMessageOrigin?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Extra inbound `postMessage` origins merged with {@link DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES}.
|
|
60
|
+
* Each entry is a host suffix (e.g. `localhost`) or full origin. Pass `['*']` to accept any origin.
|
|
61
|
+
*/
|
|
62
|
+
allowedMessageOrigins?: string[];
|
|
40
63
|
}
|
|
41
64
|
/**
|
|
42
65
|
* **Off** at start. While enabled:
|
|
@@ -61,6 +84,7 @@ interface CombosDevelopmentToolSystemParams {
|
|
|
61
84
|
declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {
|
|
62
85
|
static systemName: string;
|
|
63
86
|
private postMessageOrigin;
|
|
87
|
+
private allowedMessageOrigins;
|
|
64
88
|
private enabled;
|
|
65
89
|
private outlineGo;
|
|
66
90
|
private selected;
|
|
@@ -130,6 +154,8 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
130
154
|
private resolveApplyTarget;
|
|
131
155
|
private handleApplyProperty;
|
|
132
156
|
private postSnapshotUpdate;
|
|
157
|
+
private clearSelectionAndNotify;
|
|
158
|
+
private postGameObjectDeselected;
|
|
133
159
|
private clearSelection;
|
|
134
160
|
/** Redraw the green outline only when content bounds change (movement follows via child transform). */
|
|
135
161
|
private updateSelectionOutline;
|
|
@@ -168,5 +194,13 @@ declare function readPropertyValue(go: GameObject, componentName: string, path:
|
|
|
168
194
|
|
|
169
195
|
declare function applyPropertyWithHooks(go: GameObject, componentName: string, path: string[], value: unknown): boolean;
|
|
170
196
|
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
type DevelopmentToolDeselectReason = 'parent-request' | 'pick-disabled' | 'target-removed';
|
|
198
|
+
declare function buildGameObjectDeselectedPayload(reason: DevelopmentToolDeselectReason): {
|
|
199
|
+
readonly type: "combos-development-tool:gameobject-deselected";
|
|
200
|
+
readonly reason: DevelopmentToolDeselectReason;
|
|
201
|
+
};
|
|
202
|
+
declare function shouldNotifyGameObjectDeselected(hadSelection: boolean): boolean;
|
|
203
|
+
declare function isClearSelectionMessage(data: unknown): boolean;
|
|
204
|
+
|
|
205
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, applyPropertyValue, applyPropertyWithHooks, buildGameObjectDeselectedPayload, buildGameObjectSnapshot, isAllowedMessageOrigin, isClearSelectionMessage, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor, shouldNotifyGameObjectDeselected };
|
|
206
|
+
export type { CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, DevelopmentToolDeselectReason, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
|
|
@@ -12,6 +12,10 @@ const COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS = 'combos-development-tool:set-success
|
|
|
12
12
|
const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh';
|
|
13
13
|
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
14
14
|
const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gameobject-selected';
|
|
15
|
+
/** Parent → iframe: clear the current in-canvas selection outline. */
|
|
16
|
+
const COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION = 'combos-development-tool:clear-selection';
|
|
17
|
+
/** Emitted to `window.parent` when the current selection is cleared. */
|
|
18
|
+
const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED = 'combos-development-tool:gameobject-deselected';
|
|
15
19
|
/** Parent → iframe: apply a value to a component field (live preview). */
|
|
16
20
|
const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = 'combos-development-tool:apply-property';
|
|
17
21
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
@@ -39,6 +43,74 @@ class CombosDevelopmentToolTarget extends Component {
|
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
47
|
+
const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES = [
|
|
48
|
+
'knoffice.tech',
|
|
49
|
+
'converge.ai',
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* Returns whether `origin` is allowed by `allowed`.
|
|
53
|
+
*
|
|
54
|
+
* Each entry in `allowed` is either:
|
|
55
|
+
* - a **host suffix** (e.g. `knoffice.tech`) — matches that host and `*.knoffice.tech`;
|
|
56
|
+
* - a **full origin** (e.g. `https://creator.knoffice.tech`) — exact match;
|
|
57
|
+
* - `'*'` — accept any origin (escape hatch).
|
|
58
|
+
*/
|
|
59
|
+
function isAllowedMessageOrigin(origin, allowed) {
|
|
60
|
+
if (allowed.includes('*')) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
if (allowed.length === 0) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = new URL(origin);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const originLower = origin.toLowerCase();
|
|
74
|
+
const hostLower = parsed.hostname.toLowerCase();
|
|
75
|
+
for (const entry of allowed) {
|
|
76
|
+
const trimmed = entry.trim();
|
|
77
|
+
if (!trimmed) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (trimmed.includes('://')) {
|
|
81
|
+
if (originLower === trimmed.toLowerCase()) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const suffix = trimmed.toLowerCase().replace(/^\./, '');
|
|
87
|
+
if (hostLower === suffix || hostLower.endsWith(`.${suffix}`)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
/** Defaults plus any extra entries (deduped). `['*']` alone accepts any origin. */
|
|
94
|
+
function mergeAllowedMessageOrigins(extra) {
|
|
95
|
+
if (!extra?.length) {
|
|
96
|
+
return [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES];
|
|
97
|
+
}
|
|
98
|
+
if (extra.includes('*')) {
|
|
99
|
+
return ['*'];
|
|
100
|
+
}
|
|
101
|
+
const seen = new Set();
|
|
102
|
+
const result = [];
|
|
103
|
+
for (const entry of [...DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, ...extra]) {
|
|
104
|
+
const trimmed = entry.trim();
|
|
105
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
seen.add(trimmed);
|
|
109
|
+
result.push(trimmed);
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
42
114
|
function isSceneSourceAnchor(v) {
|
|
43
115
|
return (!!v &&
|
|
44
116
|
typeof v === 'object' &&
|
|
@@ -277,6 +349,22 @@ function applyPropertyWithHooks(go, componentName, path, value) {
|
|
|
277
349
|
return applyPropertyValue(go, componentName, path, value);
|
|
278
350
|
}
|
|
279
351
|
|
|
352
|
+
function buildGameObjectDeselectedPayload(reason) {
|
|
353
|
+
return {
|
|
354
|
+
type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED,
|
|
355
|
+
reason,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function shouldNotifyGameObjectDeselected(hadSelection) {
|
|
359
|
+
return hadSelection;
|
|
360
|
+
}
|
|
361
|
+
function isClearSelectionMessage(data) {
|
|
362
|
+
if (!data || typeof data !== 'object') {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
return data.type === COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION;
|
|
366
|
+
}
|
|
367
|
+
|
|
280
368
|
const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
281
369
|
/**
|
|
282
370
|
* **Off** at start. While enabled:
|
|
@@ -302,6 +390,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
302
390
|
constructor() {
|
|
303
391
|
super(...arguments);
|
|
304
392
|
this.postMessageOrigin = '*';
|
|
393
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins();
|
|
305
394
|
this.enabled = false;
|
|
306
395
|
this.outlineGo = null;
|
|
307
396
|
this.selected = null;
|
|
@@ -334,6 +423,9 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
334
423
|
}
|
|
335
424
|
};
|
|
336
425
|
this.onWindowMessage = (e) => {
|
|
426
|
+
if (!isAllowedMessageOrigin(e.origin, this.allowedMessageOrigins)) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
337
429
|
const d = e.data;
|
|
338
430
|
if (!d || typeof d !== 'object')
|
|
339
431
|
return;
|
|
@@ -349,6 +441,9 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
349
441
|
else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {
|
|
350
442
|
this.requestSceneRescan();
|
|
351
443
|
}
|
|
444
|
+
else if (isClearSelectionMessage(d)) {
|
|
445
|
+
this.clearSelectionAndNotify('parent-request');
|
|
446
|
+
}
|
|
352
447
|
else if (d.type === COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY) {
|
|
353
448
|
this.handleApplyProperty(d);
|
|
354
449
|
}
|
|
@@ -378,6 +473,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
378
473
|
static { this.systemName = 'CombosDevelopmentToolSystem'; }
|
|
379
474
|
init(params) {
|
|
380
475
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
476
|
+
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
381
477
|
if (typeof window !== 'undefined') {
|
|
382
478
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
383
479
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onWindowSetPaused);
|
|
@@ -407,7 +503,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
407
503
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
408
504
|
this.detachAllPicks();
|
|
409
505
|
this.restoreDisabledGameEvents();
|
|
410
|
-
this.
|
|
506
|
+
this.clearSelectionAndNotify('pick-disabled');
|
|
411
507
|
}
|
|
412
508
|
/** Programmatic toggle (same effect as events). */
|
|
413
509
|
setEnabled(on) {
|
|
@@ -415,7 +511,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
415
511
|
return;
|
|
416
512
|
this.enabled = on;
|
|
417
513
|
if (!on) {
|
|
418
|
-
this.
|
|
514
|
+
this.clearSelectionAndNotify('pick-disabled');
|
|
419
515
|
this.detachAllPicks();
|
|
420
516
|
this.restoreDisabledGameEvents();
|
|
421
517
|
this.postSetSuccess(false);
|
|
@@ -493,7 +589,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
493
589
|
else if (type === OBSERVER_TYPE.REMOVE) {
|
|
494
590
|
this.releasePick(gameObject);
|
|
495
591
|
if (this.selected === gameObject) {
|
|
496
|
-
this.
|
|
592
|
+
this.clearSelectionAndNotify('target-removed');
|
|
497
593
|
}
|
|
498
594
|
}
|
|
499
595
|
}
|
|
@@ -869,6 +965,21 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
869
965
|
}, this.postMessageOrigin);
|
|
870
966
|
}
|
|
871
967
|
}
|
|
968
|
+
clearSelectionAndNotify(reason) {
|
|
969
|
+
const hadSelection = this.selected != null;
|
|
970
|
+
this.clearSelection();
|
|
971
|
+
if (!shouldNotifyGameObjectDeselected(hadSelection)) {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
this.postGameObjectDeselected(reason);
|
|
975
|
+
}
|
|
976
|
+
postGameObjectDeselected(reason) {
|
|
977
|
+
const payload = buildGameObjectDeselectedPayload(reason);
|
|
978
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
979
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
980
|
+
}
|
|
981
|
+
this.game.emit(payload.type, { reason });
|
|
982
|
+
}
|
|
872
983
|
clearSelection() {
|
|
873
984
|
this.selected = null;
|
|
874
985
|
this.invalidateOutlineBounds();
|
|
@@ -918,8 +1029,8 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
|
|
|
918
1029
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
919
1030
|
Object.assign(CombosDevelopmentToolSystem$1, {
|
|
920
1031
|
packageName: "@combos-fun/plugin-development-tool",
|
|
921
|
-
packageVersion: "0.0.
|
|
1032
|
+
packageVersion: "0.0.25",
|
|
922
1033
|
});
|
|
923
1034
|
|
|
924
|
-
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
|
|
1035
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, applyPropertyValue, applyPropertyWithHooks, buildGameObjectDeselectedPayload, buildGameObjectSnapshot, isAllowedMessageOrigin, isClearSelectionMessage, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor, shouldNotifyGameObjectDeselected };
|
|
925
1036
|
//# sourceMappingURL=plugin-development-tool.esm.js.map
|