WM App Object

This is the app class which is created under the WM version 4.x script

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/6895/28424/WM%20App%20Object.js

  1. // ==UserScript==
  2. // @name WM App Object
  3. // @namespace MerricksdadWMAppObject
  4. // @description This is the app class which is created under the WM version 4.x script
  5. // @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/
  6. // @version 4.0.0.4
  7. // @copyright Charlie Ewing except where noted
  8. // ==/UserScript==
  9.  
  10. //this script requires some functions in the WM Common Library
  11. //this script needs access to a pre-defined JSON object
  12.  
  13.  
  14. (function(){
  15.  
  16. var checkBox=function(l,d,c,n){return ({type:"checkbox",label:l,"default":d||false,kids:c,newitem:n});}
  17. var hidden=function(l,d,c){return ({type:"hidden",label:l,"default":d,kids:c});}
  18. var optionBlock=function(l,c,hideSelectAll,n){hideSelectAll=hideSelectAll||false;return ({type:"optionblock",label:l,kids:c,hideSelectAll:hideSelectAll,newitem:n});}
  19. var separator=function(l,s,c,hideSelectAll){hideSelectAll=hideSelectAll||false; return ({type:"separator",label:l,section:s,kids:c}); }
  20. var section=function(l,c){return ({type:"section",label:l,kids:c});}
  21. var tabSection=function(l,c){return ({type:"tab",label:l,kids:c});}
  22. var inputBox=function(l,d,n){return ({type:"float",label:l,"default":(d||0),newitem:n});}
  23. var textArea=function(l,d,n){return ({type:"textarea",label:l,"default":(d||0),newitem:n});}
  24. var colorBox=function(l,d,n){return ({type:"colorbox",label:l,"default":(d||"black"),newitem:n});}
  25. var button=function(l,s){return ({type:"button",label:l,script:s});}
  26. var anchor=function(l,u,t){return ({type:"link",label:l,href:u,title:(t||'')});}
  27.  
  28. //***************************************************************************************************************************************
  29. //***** App Class
  30. //***************************************************************************************************************************************
  31. WM.App = function(params){try{
  32. this.objType="app";
  33. var self=this;
  34. //expected: id, name, namespace, icon
  35. params=params||{};
  36.  
  37. //create the masterswitch
  38. var testms=WM.quickOpts.masterSwitch[params.appID];
  39. WM.quickOpts.masterSwitch[params.appID]=(testms==null||testms=="undefined")?true:testms;
  40.  
  41. //set defaults
  42. this._enabled=WM.quickOpts.masterSwitch[params.appID]||false;
  43. this._paused=false;
  44. this.tests={};
  45. this.typesPaused=[];
  46. this.pausedTypesListNodes={};
  47. this._acceptCount=0;
  48. this._failCount=0;
  49. this.node=null;
  50. this.expanded=false;
  51. this.kids=[]; //contains additional filtered apps
  52. //setup config for this sidekick
  53. this.opts = {};
  54. this.config = new Config({
  55. storageName:"settings_"+params.appID+"_"+(WM.quickOpts.useGlobalSettings?"global":WM.currentUser.profile),
  56. onSave:WM.onSave,
  57. title:"FB Wall Manager "+WM.version+(WM.quickOpts.useGlobalSettings?" (!! Global Settings !!)":""),
  58. logo:createElement("span",{}[
  59. createElement("img",{className:"logo",src:"",textContent:"v"+WM.version}),
  60. createElement("text","v"+WM.version)
  61. ]),
  62. css:(
  63. WM.console.dynamicIcons()+
  64. jsForms.globalStyle()
  65. ),
  66. settings:{
  67. btn_useGlobal:{
  68. type:"button",
  69. label:"Use Global Settings",
  70. title:"Switch to using a global storage for settings. Those settings can then be used by other accounts (not browser profiles).",
  71. script:function(){
  72. if (WM.quickOpts.useGlobalSettings||false) {
  73. //already using global settings
  74. return;
  75. }
  76. if (confirm("Switch to using global (shared) settings?")){
  77. WM.quickOpts.useGlobalSettings=true;
  78. WM.saveQuickOpts();
  79. this.config.title = "FB Wall Manager "+WM.version+" (!! Global Settings !!))";
  80. this.config.storageName = "settings_"+params.appID+"_global";
  81. this.config.values=this.config.read();
  82. this.config.configure();
  83. this.config.reload();
  84. }
  85. },
  86. },
  87. btn_useOwnProfile:{
  88. type:"button",
  89. label:"Use Profile Settings",
  90. title:"Switch to using your own profile storage for settings.",
  91. script:function(){
  92. if (!(WM.quickOpts.useGlobalSettings||false)) {
  93. //already using profile settings
  94. return;
  95. }
  96. if (confirm("Switch to using your own profile settings?")){
  97. WM.quickOpts.useGlobalSettings=false;
  98. WM.saveQuickOpts();
  99. this.config.title = "FB Wall Manager "+WM.version;
  100. this.config.storageName = "settings_"+params.appID+"_"+WM.currentUser.profile;
  101. this.config.values=this.config.read();
  102. this.config.configure();
  103. this.config.reload();
  104. }
  105. },
  106. },
  107. },
  108. });
  109. //setup user defined accept texts
  110. try{
  111. if (WM.quickOpts.userDefinedTypes) {
  112. this.userDefinedTypes=WM.quickOpts.userDefinedTypes[params.appID]||{};
  113. } else {
  114. this.userDefinedTypes={}; //create a default here
  115. WM.quickOpts.userDefinedTypes={};
  116. WM.quickOpts.userDefinedTypes[params.appID]={};
  117. WM.saveQuickOpts();
  118. }
  119. }catch(e){log("WM.App.init: userDefinedTypes: "+e);}
  120.  
  121. //use passed params
  122. for (var p in params) this[p]=params[p];
  123.  
  124. //enable/disable all sidekick functions
  125. this.enable=function(){try{this.enabled=true;}catch(e){log("WM.App.enable: "+e);}};
  126. this.disable=function(){try{this.enabled=false;}catch(e){log("WM.App.disable: "+e);}};
  127. this.toggle=function(){try{this.enabled=!this.enabled;}catch(e){log("WM.App.toggle: "+e);}};
  128.  
  129. //pause collection for this app
  130. this.pause=function(){try{this.paused=true;}catch(e){log("WM.App.pause: "+e);}}
  131. this.unPause=function(){try{this.paused=false;}catch(e){log("WM.App.unPause: "+e);}}
  132.  
  133. //user defined types
  134. this.addUDT=function(params,drawOnly){try{
  135. //validate params or ask for input
  136. if (!exists(params) || !params.id) {
  137. params=params||{};
  138. var udtname=prompt("Enter the text name of the bonus type you wish to make (ie 'Horse')\n","");
  139. var udtid=this.appID+udtname.noSpaces().toLowerCase();
  140. udtid=prompt("OK, your type will read as '"+udtname+"'.\nNow modify this bonus type code to suit your needs.\n\nTip: You should prefix this code with the appID '"+this.appID+"', but it is not required.\nTip: Most sidekicks use lowercase and no spaces, but again, this is not a requirement.\n", udtid);
  141. if (udtid.trim()){
  142. params.id=udtid.trim();
  143. params.name=udtname;
  144. } else {
  145. alert("You supplied a blank user defined type ID. No type was created.");
  146. return false;
  147. }
  148. }
  149. if (!drawOnly){
  150. this.userDefinedTypes[params.id]=params.name;
  151. WM.quickOpts.userDefinedTypes[this.appID]=this.userDefinedTypes;
  152. WM.saveQuickOpts();
  153. }
  154. //draw the udt node
  155. if (this.udtNode){
  156. this.udtNode.appendChild(
  157. createElement("div",{className:"listItem"},[
  158. createElement("label",{textContent:params.id+" : "}),
  159. createElement("input",{value:params.name,title:"The display name of this type, used wherever bonus types are identified or selected.", onchange:function(){
  160. self.userDefinedTypes[params.id]=this.value;
  161. WM.quickOpts.userDefinedTypes[self.appID]=self.userDefinedTypes;
  162. WM.saveQuickOpts();
  163. }}),
  164. createElement("div",{className:"littleButton oddOrange", title:"Remove User-Defined Type"},[
  165. createElement("img",{className:"resourceIcon trash" +WM.opts.littleButtonSize,onclick:function(){
  166. var ask=WM.opts.appsConfirmDeleteUDT;
  167. if (!ask || (ask && confirm("Delete User Defined Type?"))) {
  168. delete self.userDefinedTypes[params.id];
  169. WM.quickOpts.userDefinedTypes[self.appID]=self.userDefinedTypes;
  170. WM.saveQuickOpts();
  171. remove (this.parentNode.parentNode);
  172. }
  173. }})
  174. ]),
  175. (this.accText[params.id]||null)?createElement("span",{title:"The type id you created exactly matches one provided by the sidekick for this app. If you did not intend to overwrite that bonus's display text, you may wish to create another type id and destroy this one.",style:"color:red;",textContent:"Overwrites a sidekick-provided bonus type id."}):null,
  176. ])
  177. );
  178. }
  179. }catch(e){log("WM.App.addUDT: "+e);}}
  180.  
  181. //unpause all bonus types for this app
  182. this.unpauseAllTypes=function(){try{
  183. for (var i=this.typesPaused.length-1;i>=0;i--){
  184. WM.unPauseByType(this,this.typesPaused[i]);
  185. }
  186. }catch(e){log("WM.App.unpauseAllTypes: "+e);}};
  187.  
  188.  
  189. //mass set priority for entire app post collection
  190. this.setPriority=function(n){try{
  191. for (var p in WM.posts) {
  192. var post=WM.posts[p];
  193. if (post.app==this) post.setPriority(n);
  194. }
  195. }catch(e){log("WM.App.setPriority: "+e);}};
  196.  
  197. //mass set priority for all posts of type
  198. this.setPriorityByType=function(w,n){try{
  199. for (var p in WM.posts) {
  200. var post=WM.posts[p];
  201. if (post.app==this && post.which==w) post.setPriority(n);
  202. }
  203. }catch(e){log("WM.App.setPriorityByType: "+e);}};
  204. //reset accept/fail counters
  205. this.resetCounter=function(){try{
  206. this.acceptCount=0;
  207. this.failCount=0;
  208. }catch(e){log("WM.App.resetCounter: "+e);}};
  209.  
  210. //reset all config options for this app
  211. //except those outside the standard branch (dontsteal,blockautolike,etc.)
  212. this.resetConfig=function(){try{
  213. var ask=WM.opts.configConfirmRestore;
  214. if (!ask || (ask && confirm("Restore sidekick settings to defaults?"))) {
  215. this.config.configure({reset:true});
  216. this.config.save();
  217. }
  218. }catch(e){log("WM.App.resetConfig: "+e);}};
  219. //fetch posts only for this app
  220. //normally used for initial fetching only
  221. this.fetchPosts=function(){try{
  222. WM.fetch({bypassPause:true, apps:this});
  223. }catch(e){log("WM.App.fetchPosts: "+e);}};
  224.  
  225. this.fetchNewer=function(){try{
  226. WM.fetch({
  227. newer:true,
  228. apps:this,
  229. bypassPause:true,
  230. bypassAppDisabled:true
  231. });
  232. }catch(e){log("WM.App.fetchNewer: "+e);}};
  233.  
  234. this.fetchOlder=function(){try{
  235. WM.fetch({
  236. older:true,
  237. apps:this,
  238. bypassPause:true,
  239. bypassAppDisabled:true
  240. });
  241. }catch(e){log("WM.App.fetchOlder: "+e);}};
  242.  
  243. //get a list of posts for this app from the global posts list
  244. this.__defineGetter__("posts",function(){try{
  245. return matchByParam(WM.posts,"app",this,"object");
  246. }catch(e){log("WM.App.getPosts: "+e);}});
  247. //detect if this sidekick said it was chrome compatible
  248. this.__defineGetter__("isVer3",function(){try{
  249. return this.flags.postMessageCompatible || this.flags.worksInChrome;
  250. }catch(e){log("WM.App.isVer3: "+e);}});
  251.  
  252. //detect if is paused
  253. this.__defineGetter__("paused",function(){try{
  254. return this._paused;
  255. }catch(e){log("WM.App.paused: "+e);}});
  256. this.__defineSetter__("paused",function(v){try{
  257. this._paused=v;
  258. //update the sidekick page button graphics
  259. var btn=this.pauseButtonNode;
  260. if (btn) {
  261. var btnSize=WM.opts.littleButtonSize;
  262. with (btn.parentNode)
  263. className=className.swapWordB(this._paused,"oddGreen","oddOrange");
  264. with (btn)
  265. className=className.swapWordB(this._paused,"playRight"+btnSize,"pause"+btnSize);
  266. }
  267. //do events
  268. if (this._paused) WM.rulesManager.doEvent("onAppPaused",this);
  269. else WM.rulesManager.doEvent("onAppUnpaused",this);
  270. }catch(e){log("WM.App.paused: "+e);}});
  271. //detect if is enabled
  272. this.__defineGetter__("enabled",function(){try{
  273. return this._enabled;
  274. }catch(e){log("WM.App.enabled: "+e);}});
  275. this.__defineSetter__("enabled",function(v){try{
  276. this._enabled=v;
  277. //update the WM.quickOpts
  278. WM.quickOpts.masterSwitch[this.appID]=this._enabled;
  279. WM.saveQuickOpts();
  280. //update the sidekick page graphics
  281. if (this.toggleNode) this.toggleNode.checked=this._enabled;
  282. if (this.node) with (this.node){
  283. className=className.swapWordB(this._enabled,"enabled","disabled");
  284. }
  285. //do events
  286. if (this._enabled) WM.rulesManager.doEvent("onAppEnabled",this);
  287. else WM.rulesManager.doEvent("onAppDisabled",this);
  288. }catch(e){log("WM.App.enabled: "+e);}});
  289. this.__defineGetter__("acceptCount",function(){try{
  290. return this._acceptCount;
  291. }catch(e){log("WM.App.acceptCount: "+e);}});
  292. this.__defineSetter__("acceptCount",function(v){try{
  293. this._acceptCount=v;
  294. if (this.acceptCounterNode) this.acceptCounterNode.textContent=v;
  295. }catch(e){log("WM.App.acceptCount: "+e);}});
  296. this.__defineGetter__("failCount",function(){try{
  297. return this._failCount;
  298. }catch(e){log("WM.App.failCount: "+e);}});
  299. this.__defineSetter__("failCount",function(v){try{
  300. this._failCount=v;
  301. if (this.failCounterNode) this.failCounterNode.textContent=v;
  302. }catch(e){log("WM.App.failCount: "+e);}});
  303.  
  304. this.__defineGetter__("totalCount",function(){try{
  305. return this._failCount+this._acceptCount;
  306. }catch(e){log("WM.App.totalCount: "+e);}});
  307.  
  308. //detect if this app is bundled with another app
  309. //return the main app in this bundle
  310. this.__defineGetter__("synApp",function(){try{
  311. return this.parent||this;
  312. }catch(e){log("WM.App.synApp: "+e);}});
  313. this.toggleContent=function(){try{
  314. this.expanded=!this.expanded;
  315. var btnSize=WM.opts.littleButtonSize;
  316. with (this.contentNode)
  317. className=className.swapWordB(this.expanded,"expanded","collapsed");
  318. with (this.toggleImgNode)
  319. className=className.swapWordB(this.expanded,"treeCollapse"+btnSize,"treeExpand"+btnSize);
  320. }catch(e){log("WM.App.toggleContent: "+e);}};
  321.  
  322. this.showConfig=function(){try{
  323. this.config.open();
  324. }catch(e){log("WM.App.showConfig: "+e);}};
  325.  
  326. this.disableOpt=function(w){try{
  327. this.opts[w]=false;
  328. this.config.set(w,false);
  329. this.config.save();
  330. }catch(e){log("WM.App.disableOpt: "+e);}};
  331.  
  332. this.enableOpt=function(w){try{
  333. this.opts[w]=true;
  334. this.config.set(w,true);
  335. this.config.save();
  336. }catch(e){log("WM.App.enableOpt: "+e);}};
  337. //add menu elements
  338. try{
  339. /* no longer used in WM3
  340. if (this.menu) {
  341. //prefix all menu elements with the appID
  342. this.menu=WM.dock.fixMenu(this.menu,this.appID);
  343. //append this app's menu settings
  344. this.settingsBranch=WM.config.append({branch:"wmtab_games",data:this.menu});
  345. }
  346. //prefix all test returns with the appID
  347. WM.dock.fixTests(this.tests,this);
  348. //prefix all accept text id's with the appID
  349. WM.dock.fixAcceptTexts(this);
  350. */
  351. //new method
  352. if (this.menu) this.config.append({data:this.menu});
  353. //I should really move these into the sidekick realm
  354. var data={};
  355. data["dynamic"+this.appID]=checkBox(this.name+" ("+this.appID+")",true);
  356. WM.config.append({branch:"enableDynamic",data:data});
  357.  
  358. data={}; data[this.appID+"dontsteal"]=checkBox(this.name);
  359. WM.config.append({branch:"dontstealBlock",data:data});
  360. data={}; data["hide"+this.appID]=checkBox(this.name);
  361. WM.config.append({branch:"filterapps",data:data});
  362. data={}; data["nolike"+this.appID]=checkBox(this.name);
  363. WM.config.append({branch:"blockautolikebygame",data:data});
  364. } catch(e) {log("WM.App.init:addMenuElements: "+e);};
  365. //draw to #sidekickList (WM.console.sidekickNode)
  366. try{
  367. WM.console.sidekickNode.appendChild(
  368. this.node=createElement("div",{className:"listItem "+((this.enabled)?"enabled":"disabled")},[
  369. createElement("div",{className:"line"},[
  370. createElement("div",{className:"littleButton",title:"Toggle Content",onclick:function(){self.toggleContent();}},[
  371. this.toggleImgNode=createElement("img",{className:"resourceIcon "+(this.expanded?"treeCollapse"+WM.opts.littleButtonSize:"treeExpand"+WM.opts.littleButtonSize)}),
  372. ]),
  373. this.toggleNode=createElement("input",{type:"checkbox",checked:this.enabled,onchange:function(){
  374. self.enabled=this.checked;
  375. with (self.node) className=className.toggleWordB(!this.checked,"disabled");
  376. }}),
  377. (this.icon)?createElement("img",{className:"icon crisp", src:this.icon,style:"width: 32px;vertical-align: middle"}):null,
  378. createElement("label",{textContent: this.name}),
  379. //toolbox
  380. createElement("div",{className:"littleButton odd"+(this.paused?"Green":"Orange"), title:"Pause/Unpause"},[
  381. this.pauseButtonNode=createElement("img",{className:"resourceIcon "+(this.paused?"playRight":"pause")+WM.opts.littleButtonSize,onclick:function(){self.paused=!self.paused;}})]),
  382. createElement("div",{className:"littleButton oddBlue", title:"Reset config for this app"},[
  383. createElement("img",{className:"resourceIcon uncheckAll"+WM.opts.littleButtonSize,onclick:function(){self.resetConfig();}})]),
  384. //createElement("div",{className:"littleButton oddBlue", title:"Fetch Newer Posts"},[
  385. //createElement("img",{className:"resourceIcon rssUpRight"+WM.opts.littleButtonSize,onclick:function(){self.fetchNewer();}})]),
  386. //createElement("div",{className:"littleButton", title:"Fetch Older Posts"},[
  387. //createElement("img",{className:"resourceIcon rssDownLeft" +WM.opts.littleButtonSize,onclick:function(){self.fetchOlder();}})]),
  388. //new sidekick config button
  389. this.configButton=createElement("button",{textContent:"Options", onclick:function(){self.config.open();}}),
  390. ]),
  391. this.contentNode=createElement("div",{className:"subsection "+(this.expanded?"expanded":"collapsed")},[
  392. createElement("div",{className:"line"},[
  393. createElement("label",{textContent:"App ID:"}),
  394. createElement("span",{textContent:this.appID}),
  395. ]),
  396. createElement("div",{className:"line"},[
  397. createElement("label",{textContent:"Support Provided By:"}),
  398. (this.desc)?createElement("span",{textContent: this.desc}):null, //provided in sidekick block
  399. ]),
  400. createElement("div",{className:"line"},[
  401. createElement("label",{textContent:"Sidekick Help Link:"}),
  402. (this.helpLink)?createElement("a",{href:this.helpLink,textContent:this.helpLink}):null, //provided in sidekick block
  403. ]),
  404. //browsers supported
  405. createElement("div",{className:"line"},[
  406. createElement("label",{textContent:"Browsers Supported:",style:"vertical-align:top;"}),
  407. createElement("img",{className:"resourceIcon firefox16", style:"display:inline-block;",title:"FireFox"}),
  408. (this.isVer3)?createElement("img",{className:"resourceIcon chrome16", style:"display:inline-block;",title:"Google Chrome"}):null,
  409. ]),
  410. //types paused subbox
  411. createElement("div",{className:"line"},[
  412. createElement("label",{textContent:"Types Paused:",title:"This is a list of bonus types that are currently paused for this app."}),
  413. createElement("div",{className:"littleButton oddGreen",onclick:function(){self.unpauseAllTypes();},title:"Unpause all types by this app."},[
  414. createElement("img",{className:"resourceIcon playRight"+WM.opts.littleButtonSize}),
  415. ]),
  416. this.typesPausedNode=createElement("div",{className:"subsection"}),
  417. ]),
  418. //attached apps
  419. createElement("div",{className:"line"},[
  420. createElement("label",{textContent:"Attached Apps:",title:"Additional apps filtered and processed by this sidekick."}),
  421. this.filtersNode=createElement("div",{className:"subsection"}),
  422. ]),
  423. //helpers subbox
  424. createElement("div",{className:"line"},[
  425. createElement("label",{textContent:"Helpers:",title:"Sidekick helpers"}),
  426. this.helpersNode=createElement("div",{className:"subsection"}),
  427. ]),
  428. //user defined types subbox
  429. createElement("div",{className:"line"},[
  430. createElement("label",{textContent:"User-Defined Types:",title:"User Defined Types ('which')"}),
  431. createElement("div",{className:"littleButton oddGreen",onclick:function(){self.addUDT();},title:"Add New User Defined Type"},[
  432. createElement("img",{className:"resourceIcon plus"+WM.opts.littleButtonSize}),
  433. ]),
  434. this.udtNode=createElement("div",{className:"subsection"}),
  435. ]),
  436. ]),
  437. ])
  438. );
  439. }catch(e){log("WM.App.init:addSidekickElement: "+e);};
  440. //create feed filters for this app
  441. try{
  442. var feeds=WM.feedManager.feeds;
  443. for (var f=0,len=feeds.length;f<len;f++){
  444. feeds[f].addFilter({id:"app_"+this.appID});
  445. }
  446. }catch(e){log("WM.App.init:createFeedFilters: ")+e;}
  447.  
  448. //draw to collection filter coolbar
  449. try{
  450. //create game filter buttons on the WM.console
  451. var coolBar = WM.console.collectTabControl;
  452. if (coolBar) {
  453. //add a tab for this filter
  454. var tab = coolBar.addTab({
  455. text:(this.name||""),
  456. image:(this.icon||null),
  457. appFilter:this.appID,
  458. onSelect:WM.setAppFilter,
  459. selected:(WM.quickOpts.filterApp==this.appID),
  460. });
  461. this.collectionTabNode=tab.buttonNode;
  462. //force the image to have the 'crisp' drawing style
  463. tab.buttonNode.childNodes[0].className="icon crisp";
  464. //add accept/fail counters
  465. this.failCount=0;
  466. this.acceptCount=0;
  467. tab.buttonNode.insertBefore(
  468. createElement("div",{className:"accFailBlock"},[
  469. this.failCounterNode=createElement("span",{className:"fail",textContent:"0"}),
  470. this.acceptCounterNode=createElement("span",{className:"accept",textContent:"0"}),
  471. ])
  472. , tab.textNode);
  473. }
  474. } catch(e) {log("WM.App.init:addConsoleElement: "+e);};
  475. //show additional filtered apps
  476. try{
  477. if (isArrayAndNotEmpty(this.addFilters)) {
  478. for (var f,filt;(filt=this.addFilters[f]);f++){
  479. //create an app object for this filter
  480. filt.parent=this;
  481. this.kids.push(new WM.App(filt));
  482. if (this.filtersNode) this.filtersNode.appendChild(
  483. createElement("div",{className:"line"},[
  484. createElement("img",{className:"icon crisp", src:filt.icon||null}),
  485. createElement("text",filt.name),
  486. ])
  487. );
  488. }
  489. }
  490. } catch(e) {log("WM.App.init:addFilteredApps: "+e);};
  491. //draw my user defined types
  492. try{
  493. for (var u in this.userDefinedTypes){
  494. this.addUDT({id:u,name:this.userDefinedTypes[u]},true);
  495. }
  496. }catch(e){log("WM.App.init: drawUDTs: "+e);}
  497. //do events
  498. WM.rulesManager.doEvent("onSidekickReady",this);
  499. return self;
  500. }catch(e){log("WM.App.init: "+e);}};
  501.  
  502.  
  503.  
  504. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址