بۇ قوليازمىنى بىۋاسىتە قاچىلاشقا بولمايدۇ. بۇ باشقا قوليازمىلارنىڭ ئىشلىتىشى ئۈچۈن تەمىنلەنگەن ئامبار بولۇپ، ئىشلىتىش ئۈچۈن مېتا كۆرسەتمىسىگە قىستۇرىدىغان كود: // @require https://update.greasyfork.org/scripts/6899/27565/WM%20Test%20Object.js
// ==UserScript==
// @name WM Test Object
// @namespace MerricksdadWMHostObject
// @description This is the post test class which is created under the WM version 4.x script
// @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/
// @version 4.0.0.0
// @copyright Charlie Ewing except where noted
// ==/UserScript==
//this script requires some functions in the WM Common Library
//this script needs access to a pre-defined JSON object
(function(){
//***************************************************************************************************************************************
//***** Test Class
//***************************************************************************************************************************************
WM.Test = function(params){try{
this.objType="test";
var self=this;
params=params||{};
//defaults
this.enabled=!(params.disabled||false); //check for WM2 disabled param
this.expanded=true;
this.title="";
this.search=[]; //strings array
this.find=""; //string
this.findArray=[]; //string array
this.kids=[]; //test array
this.subTests=[]; //strings array
this.parent=null;
this.appID="";
this.ret="dynamic";
this._findMode="basic";
this.subNumRange={low:0,high:0};
this._isGlobal=false;
this.__defineGetter__("saveableData",function(){try{
var dat={};
//dat.id=this.id;
dat.label=this.title;
dat.enabled=this.enabled;
dat.search=this.search;
dat.find=(this.findMode=="basic")?this.findArray:this.find;
dat.ret=this.ret;
dat.expanded=this.expanded;
if (this.findMode=="subtests") dat.subTests=this.subTests;
if (this.findMode=="subnumrange") {
dat.subNumRange=this.subNumRange.low+","+this.subNumRange.high;
}
if (this.findMode=="regex") dat.regex=this.regex;
dat.appID=this.appID;
dat.kids=[];
if (isArrayAndNotEmpty(this.kids)) for (var i=0,kid;(kid=this.kids[i]);i++) {
dat.kids.push(kid.saveableData);
}
return dat;
}catch(e){log("WM.Test.saveableData: "+e);}});
//set/get wether this test is saved as global or profile
this.__defineGetter__("isGlobal",function(){try{
return this._isGlobal;
}catch(e){log("WM.Test.isGlobal: "+e);}});
this.__defineSetter__("isGlobal",function(v){try{
//only top level tests can be global
if (this.parent) {
confirm("Only top level tests can be set to global.");
return;
}
if (!v) {
if (!confirm("Disabling profile sharing on this test will prevent other users on this machine from loading it. Are you sure you wish to make this test locally available only?")) return;
}
this._isGlobal=v;
//make sure we have a uniqueID
//but don't destroy one that already exists
if (v && !exists(this.uniqueID)) this.uniqueID = unique();
//change the color/icon of the isGlobal button
if (this.toggleGlobalButton) {
var s=WM.opts.littleButtonSize;
with (this.toggleGlobalButton) className=className.swapWordB(v,"removeGlobal"+s,"addGlobal"+s);
with (this.toggleGlobalButton.parentNode) {
className=className.swapWordB(v,"oddOrange","oddGreen");
title=(v)?"Disable Profile Sharing":"Share With Other Profiles";
}
}
}catch(e){log("WM.Test.isGlobal: "+e);}});
//use passed params
for (var p in params) {
//omit specific params
if (!(["subNumRange","kids","disabled","label","find"].inArray(p)) ) {
//copy only params that make it past the checker
this[p]=params[p];
}
}
//calculate subNumRange as an object
if (exists(params.subNumRange)) {
var p=params.subNumRange.split(",");
this.subNumRange={low:p[0]||0, high:p[1]||0};
this._findMode="subnumrange";
}
//get the title from the label field
if (exists(params.label)) this.title=params.label;
//detect which findMode we are using
//subNumRange was already inspected above
if (this.regex) this._findMode="regex";
else if (exists(params.subTests)) this._findMode="subtests";
//and we default to "basic" already
//import the find field now
if (isArray(params.find)) this.findArray=params.find;
else this.find=params.find;
this.enable=function(){try{
this.enabled=true;
this.node.className=this.node.className.removeWord("disabled");
WM.grabber.save();
}catch(e){log("WM.Test.enable: "+e);}};
this.disable=function(){try{
this.enabled=false;
this.node.className=this.node.className.addWord("disabled");
WM.grabber.save();
}catch(e){log("WM.Test.disable: "+e);}};
this.remove=function(noConfirm){try{
var ask=WM.opts.dynamicConfirmDeleteTest;
if (noConfirm || (this.isGlobal && confirm("This test is shared with other profiles. Deleting it here will prevent it from loading for other users. Are you sure you wish to delete this test and its children.")) || !ask || (!this.isGlobal && ask && confirm("Delete test and all of its child nodes?"))){
//remove my data
var parentContainer=(this.parent)?this.parent.kids:WM.grabber.tests;
parentContainer.removeByValue(this);
//remove my node
remove(this.node);
doAction(WM.grabber.save);
}
}catch(e){log("WM.Test.remove: "+e);}};
this.moveUp=function(){try{
//where is this
var parentContainer=(this.parent)?this.parent.kids:WM.grabber.tests;
//only affects items not already the first in the list
//and not the only child in the list
if ((parentContainer.length>1) && (parentContainer[0]!=this)) {
//which index is this?
var myIndex=parentContainer.inArrayWhere(this);
if (myIndex != -1) {
//I have a proper index here
//who is my sibling
var sibling = parentContainer[myIndex-1];
//swap me with my sibling
parentContainer[myIndex-1]=this;
parentContainer[myIndex]=sibling;
//place my node before my sibling node
sibling.node.parentNode.insertBefore(this.node,sibling.node);
//save it
WM.grabber.save();
}
}
}catch(e){log("WM.Test.moveUp: "+e);}};
this.moveDown=function(){try{
//where is this
var parentContainer=(this.parent)?this.parent.kids:WM.grabber.tests;
//only affects items not already the last in the list
//and not the only child in the list
if ((parentContainer.length>1) && (parentContainer.last()!=this)) {
//which index is this?
var myIndex=parentContainer.inArrayWhere(this);
if (myIndex != -1) {
//I have a proper index here
//who is my sibling
var sibling = parentContainer[myIndex+1];
//swap me with my sibling
parentContainer[myIndex+1]=this;
parentContainer[myIndex]=sibling;
//place my node before my sibling node
sibling.node.parentNode.insertBefore(sibling.node,this.node);
//save it
WM.grabber.save();
}
}
}catch(e){log("WM.Test.moveDown: "+e);}};
this.moveUpLevel=function(){try{
if (this.parent) {
//this is not a top level node, so we can move it
var targetContainer=((this.parent.parent)?this.parent.parent.kids:WM.grabber.tests);
//remove from parent
this.parent.kids.removeByValue(this);
//set new parent
this.parent=(this.parent.parent||null); //never point to the top level
//move the object
targetContainer.push(this);
//move the node
if (this.parent) this.parent.kidsNode.appendChild(this.node);
else WM.console.dynamicBuild.appendChild(this.node);
//save it
WM.grabber.save();
}
}catch(e){log("WM.Test.moveUpLevel: "+e);}};
this.moveDownLevel=function(){try{
//where is this
var parentContainer=(this.parent)?this.parent.kids:WM.grabber.tests;
//create a new rule at my level
var newTest = new WM.Test({
parent:this.parent||null,
});
parentContainer.push(newTest);
//remove me from my current parent
parentContainer.removeByValue(this);
//attach me to my new parent
this.parent=newTest;
newTest.kids.push(this);
//move my node
newTest.kidsNode.appendChild(this.node);
//save it
WM.grabber.save();
}catch(e){log("WM.Test.moveDownLevel: "+e);}};
this.clone=function(){try{
var cloneTest=this.saveableData;
//global clones are not global
if (this.parent) this.parent.addChild(cloneTest);
else WM.grabber.newTest(cloneTest);
}catch(e){log("WM.Test.clone: "+e);}};
this.addChild=function(p){try{
var isNew=!exists(p);
p=p||{};
p.parent=this;
var test=new WM.Test(p);
this.kids.push(test);
if (isNew) WM.grabber.save();
}catch(e){log("WM.Test.addChild: "+e);}};
this.toggleContent=function(){try{
this.expanded=!this.expanded;
var btnSize=WM.opts.littleButtonSize;
with (this.contentNode)
className=className.swapWordB(this.expanded,"expanded","collapsed");
with (this.toggleImgNode)
className=className.swapWordB(this.expanded,"treeCollapse"+btnSize,"treeExpand"+btnSize);
WM.grabber.save();
}catch(e){log("WM.Test.toggleContent: "+e);}};
this.populateBonusList=function(){try{
var node=this.bonusNode;
var bonuses={};
//get the list of accept texts for this app
if (this.appID!="") {
if (this.appID=="*") {
//populate list with bonuses from ALL docked sidekicks
} else {
//make sure the app is ready
//if it has not yet docked, it wont be
var app=WM.apps[this.appID];
bonuses = (app?(mergeJSON(app.accText,app.userDefinedTypes)||{}):{});
}
}
//add special return values
bonuses["dynamic"]="* Dynamic grab";
bonuses["none"]="* None";
bonuses["wishlist"]="* Flaged as Wishlist";
bonuses["exclude"]="* Excluded types";
bonuses["send"]="* Send Unknown";
bonuses["doUnknown"]="* Get Unknown";
bonuses["{%1}"]="* Subtest Value";
//sort by display text
bonuses=sortCollection(bonuses,"value");
//add each element to the dropdown
var elem;
node.innerHTML=""; //wipe previous list
for (var i in bonuses) {
var showI=i.removePrefix(this.appID);
node.appendChild(
elem=createElement("option",{textContent:((bonuses[i].startsWith("*"))?"":((showI.startsWith("send"))?"Send ":"Get "))+bonuses[i], value:i, selected:(this.ret==i)})
);
}
}catch(e){log("WM.Test.populateBonusList: "+e);}};
this.populateAppList=function(){try{
var node=this.appListNode;
var a={};
for (var i in WM.apps){
a[WM.apps[i].appID]=WM.apps[i].name;
}
//add special return values
a["*"]="* All";
//add each element to the dropdown
var elem;
node.innerHTML=""; //wipe previous list
for (var i in a) {
node.appendChild(elem=createElement("option",{textContent:a[i], value:i,selected:(this.appID==i)}));
}
//sort it
elementSortChildren(node,"textContent");
}catch(e){log("WM.Test.populateAppList: "+e);}};
this.calcSearch=function(){try{
//collect the checked search fields in their listed order
if (self.searchNode) {
self.search=[];
forNodes(".//input[(@type='checkbox')]",{node:self.searchNode},function(e){
if (e && e.checked){
self.search.push(e.value);
log(e.value);
}
});
}
WM.grabber.save();
}catch(e){log("WM.Test.calcSearch: "+e);}};
this.convertToRule=function(p){try{
var rule;
WM.rulesManager.rules.push(
rule=new WM.rulesManager.Rule( WM.rulesManager.ruleFromTest( this.saveableData ) )
);
if (WM.opts.rulesJumpToNewRule){
//jump to rule view
WM.console.tabContainer.selectTab(3);
//scroll to new rule
rule.node.scrollIntoView();
}
}catch(e){log("WM.Test.convertToRule: "+e);}};
//set/get find field modes
this.__defineGetter__("findMode",function(){try{
return this._findMode;
}catch(e){log("WM.Test.findMode: "+e);}});
this.__defineSetter__("findMode",function(v){try{
var lastV = this._findMode;
this._findMode=v;
if (lastV==v) return; //no change
//enable disable regex type
this.regex=(v=="regex" || v=="regexp");
//switch to array/string find field type
//this.setFindType((v=="basic")?"array":"string");
//show the correct find field
if (this.findNode) this.findNode.value=((v=="basic")?this.findArray.join("\n"):this.find);
//show/hide the subtests box
if (this.subTestsBoxNode) with (this.subTestsBoxNode) className=className.toggleWordB((v!="subtests"),"hidden");
//show/hide the subnumrange picker
if (this.subNumRangeBoxNode) with (this.subNumRangeBoxNode) className=className.toggleWordB((v!="subnumrange"),"hidden");
WM.grabber.save();
}catch(e){log("WM.Test.findMode: "+e);}});
//draw it
try{(((this.parent)?this.parent.kidsNode:null)||$("wmDynamicBuilder")).appendChild(
this.node=createElement("div",{className:"listItem "+((this.enabled)?"enabled":"disabled")},[
createElement("div",{className:"line"},[
createElement("div",{className:"littleButton",title:"Toggle Content",onclick:function(){self.toggleContent();}},[
this.toggleImgNode=createElement("img",{className:"resourceIcon "+(this.expanded?"treeCollapse"+WM.opts.littleButtonSize:"treeExpand"+WM.opts.littleButtonSize)}),
]),
this.toggleNode=createElement("input",{type:"checkbox",checked:this.enabled,onchange:function(){
self.enabled=this.checked;
with (self.node) className=className.toggleWordB(!this.checked,"disabled");
WM.grabber.save();
}}),
createElement("label",{textContent:"Title:"}),
this.titleNode=createElement("input",{value:(this.title||""), onchange:function(){self.title=this.value; WM.grabber.save();}}),
//toolbox
createElement("div",{className:"littleButton oddOrange", title:"Remove Test"},[
createElement("img",{className:"resourceIcon trash"+WM.opts.littleButtonSize,onclick:function(){self.remove();}})]),
createElement("div",{className:"littleButton oddBlue", title:"Clone Test"},[
createElement("img",{className:"resourceIcon clone"+WM.opts.littleButtonSize,onclick:function(){self.clone();}})]),
createElement("div",{className:"littleButton oddGreen", title:"Move Up"},[
createElement("img",{className:"resourceIcon arrowUp"+WM.opts.littleButtonSize,onclick:function(){self.moveUp();}})]),
createElement("div",{className:"littleButton oddOrange", title:"Move Down"},[
createElement("img",{className:"resourceIcon arrowDown"+WM.opts.littleButtonSize,onclick:function(){self.moveDown();}})]),
createElement("div",{className:"littleButton oddGreen", title:"Move Up Level"},[
createElement("img",{className:"resourceIcon moveUpLevelLeft"+WM.opts.littleButtonSize,onclick:function(){self.moveUpLevel();}})]),
createElement("div",{className:"littleButton oddOrange", title:"Move Down Level"},[
createElement("img",{className:"resourceIcon moveInLevel"+WM.opts.littleButtonSize,onclick:function(){self.moveDownLevel();}})]),
createElement("div",{className:"littleButton oddBlue", title:"Show Source"},[
createElement("img",{className:"resourceIcon object"+WM.opts.littleButtonSize,onclick:function(){promptText(JSON.stringify(self.saveableData),true);}})]),
createElement("div",{className:"indent littleButton oddBlue", title:"Convert To Rule"},[
createElement("img",{className:"resourceIcon exportGrab"+WM.opts.littleButtonSize,onclick:function(){self.convertToRule();}})]),
createElement("div",{className:"indent littleButton "+((this.isGlobal)?"oddOrange":"oddGreen"), title:((this.isGlobal)?"Disable Profile Sharing":"Share With Other Profiles")},[
this.toggleGlobalButton=createElement("img",{className:"resourceIcon "+((this.isGlobal)?"removeGlobal":"addGlobal")+WM.opts.littleButtonSize,onclick:function(){self.isGlobal=!self.isGlobal; WM.grabber.save();}})]),
]),
this.contentNode=createElement("div",{className:"subsection "+(this.expanded?"expanded":"collapsed")},[
//appID
createElement("div",{className:"line"},[
createElement("label",{textContent:"appID:"}),
this.appIDNode=createElement("input",{value:(this.appID||""), onchange:function(){self.appID=this.value;WM.grabber.save();self.populateBonusList();}}),
this.appListNode=createElement("select",{onchange:function(){self.appIDNode.value=this.value; self.appID=this.value; WM.grabber.save(); self.populateBonusList();}}),
createElement("div",{className:"littleButton oddBlue", title:"Refresh App List"},[
createElement("img",{className:"resourceIcon refresh"+WM.opts.littleButtonSize,onclick:function(){self.populateAppList();}})]),
]),
//return type
createElement("div",{className:"line"},[
createElement("label",{textContent:"Return Type ('which'):"}),
this.retNode=createElement("input",{value:(this.ret||"dynamic"), onchange:function(){self.ret=this.value;WM.grabber.save();}}),
this.bonusNode=createElement("select",{onchange:function(){self.retNode.value=this.value; self.ret=this.value; WM.grabber.save();}}),
createElement("div",{className:"littleButton oddBlue", title:"Refresh Bonus List"},[
createElement("img",{className:"resourceIcon refresh"+WM.opts.littleButtonSize,onclick:function(){self.populateBonusList();}})]),
]),
//search list
createElement("div",{className:"line"},[
createElement("label",{textContent:"Search In Field(s):",title:"Specify fields in which to look for data. Adjust order as needed."}),
this.searchNode=createElement("div",{className:"subsection optioncontainer"},(function(){
var ret=[];
//draw first the methods we have already selected
if (isArrayAndNotEmpty(self.search)) for (var m=0; m<self.search.length; m++) {
var s = self.search[m];
ret.push(createElement("div",{className:"line"},[
createElement("div",{className:"littleButton oddGreen", title:"Move Up"},[
createElement("img",{className:"resourceIcon nomargin arrowUp16",onclick:function(){elementMoveUp(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddOrange", title:"Move Down"},[
createElement("img",{className:"resourceIcon nomargin arrowDown16",onclick:function(){elementMoveDown(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddGreen", title:"Move To Top"},[
createElement("img",{className:"resourceIcon nomargin moveTopLeft16",onclick:function(){elementMoveTop(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddOrange", title:"Move To Bottom"},[
createElement("img",{className:"resourceIcon nomargin moveBottomLeft16",onclick:function(){elementMoveBottom(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("input",{type:"checkbox",value:s,checked:true,onchange:function(){self.calcSearch();}}),
createElement("label",{textContent:s,title:WM.rulesManager.postParts[s]}),
]));
}
//draw the remaining items in their normal order
for (var m=0; m<WM.grabber.methods.length; m++){
var s = WM.grabber.methods[m];
//prevent duplicates
if (self.search.inArray(s)) continue;
ret.push(createElement("div",{className:"line"},[
createElement("div",{className:"littleButton oddGreen", title:"Move Up"},[
createElement("img",{className:"resourceIcon nomargin arrowUp16",onclick:function(){elementMoveUp(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddOrange", title:"Move Down"},[
createElement("img",{className:"resourceIcon nomargin arrowDown16",onclick:function(){elementMoveDown(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddGreen", title:"Move To Top"},[
createElement("img",{className:"resourceIcon nomargin moveTopLeft16",onclick:function(){elementMoveTop(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("div",{className:"littleButton oddOrange", title:"Move To Bottom"},[
createElement("img",{className:"resourceIcon nomargin moveBottomLeft16",onclick:function(){elementMoveBottom(this.parentNode.parentNode); self.calcSearch();}})
]),
createElement("input",{type:"checkbox",value:s,onchange:function(){self.calcSearch();}}),
createElement("label",{textContent:s,title:WM.rulesManager.postParts[s]}),
]));
}
return ret;
})()),
]),
//find mode
createElement("div",{className:"line"},[
createElement("label",{textContent:"Find Mode:",title:"Choose the mode you will use to find text."}),
this.findModeNode=createElement("select",{onchange:function(){self.findMode=this.value;}},[
createElement("option",{selected:(this.findMode=="basic"),value:"basic",textContent:"Basic",title:"Search for a list of words or phrases."}),
createElement("option",{selected:(this.findMode=="subnumrange"),value:"subnumrange",textContent:"Number Range",title:"Search for a range of numbers using an insertion point '{%1}' in your find parameter."}),
createElement("option",{selected:(this.findMode=="subtests"),value:"subtests",textContent:"Sub Tests",title:"Search for a list of words or phrases using an insertion point '{%1}' in your find parameter."}),
createElement("option",{selected:(this.findMode=="regex"),value:"regex",textContent:"Registered Expression",title:"Search for complex phrases using a regular expression."})
]),
]),
//find list
createElement("div",{className:"line"},[
createElement("label",{textContent:"Find:",title:"One per line (basic mode), or a single regular expression. First match is used, so mind the order."}),
createElement("div",{className:"subsection"},[
this.findNode=createElement("textarea",{className:"fit",textContent:((this.findMode=="basic")?this.findArray.join("\n"):this.find), onchange:function(){
if (self.findMode=="basic") self.findArray=this.value.split("\n");
else self.find=this.value;
WM.grabber.save();
}}),
])
]),
//subtests list
this.subTestsBoxNode=createElement("div",{className:("line").toggleWordB(this.findMode!="subtests","hidden")},[
createElement("label",{textContent:"Subtest Texts:",title:"Provide text replacements for the insertion point. No regular expressions."}),
createElement("div",{className:"subsection"},[
this.subTestsNode=createElement("textarea",{className:"fit",textContent:((isArray(this.subTests)?this.subTests.join("\n"):"")||""), onchange:function(){self.subTests=this.value.split("\n"); WM.grabber.save();}}),
])
]),
//subnumrange picker
this.subNumRangeBoxNode=createElement("div",{className:("line").toggleWordB(this.findMode!="subnumrange","hidden")},[
createElement("label",{textContent:"Subtest Number Range:",title:"Provide a start and end range for the insertion point."}),
this.subNumRangeLowNode=createElement("input",{value:this.subNumRange.low||0, onchange:function(){self.subNumRange.low=this.value; WM.grabber.save();}}),
this.subNumRangeHighNode=createElement("input",{value:this.subNumRange.high||0, onchange:function(){self.subNumRange.high=this.value; WM.grabber.save();}}),
]),
//kids subbox
createElement("div",{className:"line"},[
createElement("label",{textContent:"Child Tests:",title:"Child tests are nested tests which are applied to matching posts at the same time the parent test is applied. Child rules can have different return values that override the parent return value."}),
createElement("div",{className:"littleButton oddGreen",onclick:function(){self.addChild();},title:"Add Child"},[
createElement("img",{className:"resourceIcon plus"+WM.opts.littleButtonSize}),
]),
this.kidsNode=createElement("div",{className:"subsection"}),
]),
]),
])
);}catch(e){log("WM.Test.init.drawTest: "+e);}
//populate my bonus list
this.populateAppList();
this.populateBonusList();
//list the kids for this test
if (isArrayAndNotEmpty(params.kids)) for (var i=0,kid; (kid=params.kids[i]); i++) {
this.addChild(kid);
}
return self;
}catch(e){log("WM.Test.init: ")+e}};
})();