Best JavaScript code snippet using playwright-internal
Cutups.js
Source:Cutups.js  
1var CutupsSpace = ShiftSpace.Space.extend({2  attributes: {3    name: 'Cutups',4    icon: 'Cutups.png', 5    version: 0.2,6    css: 'spaces/Cutups/Cutups.css'7  },8  9  setup: function(){10    //window.visibleShifts = this.visibleShifts;11  },12  13  visibleShifts: [],  //contains object meta of shifts currently show on page i.e. { commonAncestorNode : <p>, sscutupid : 12-12-343-34234902 }14  15  removeFromVisibleShifts: function(sscutupid){16    // console.log("==================================removeFromVisibleShifts");17    for(var i=0; i < this.visibleShifts.length; i++){18      if(this.visibleShifts[i].sscutupid = sscutupid){19        delete this.visibleShifts[i];20      }21    }22    var cleanedShiftArray = this.visibleShifts.filter(function(item,index){23      return $chk(item);24    });25    this.visibleShifts = cleanedShiftArray;26  },27  28  getRangeAncestorNode: function(refObj)29  {30    // console.log('getRangeAncestorNode');31    var returnAncestor;32    var colAncestorPosition   = refObj.ancestorPosition;33    34    //get all the elements with the ancestor tagname35    var nl                    = document.getElementsByTagName(colAncestorPosition.tagName);36    var iIndex                = colAncestorPosition.ancIndex;37    var iOccuranceLength      = 0;38    var targetTextContent     = refObj.ancestorOrigTextContent;39    // console.log('blar');40    //check if the tag Name is the body then compare differently41    if (colAncestorPosition.tagName.toLowerCase() == "body")42    {43      //return (targetTextContent==ShiftSpace.orig_text_content)?document.getElementsByTagName('body')[0]:null;44      return document.body;45    }46    else47    {48      //check the number of occurances of the similar nodes49      // console.log('checking similar nodes ' + nl.length);50      for (var i=0;i<nl.length;i++)51      {52        //console.log(i);53        if(nl.item(i).textContent==targetTextContent)54        {55          iOccuranceLength++;56          //if this is the occurance index mark the node as the ancestor node57          if (iIndex==iOccuranceLength)58          returnAncestor = nl.item(i);59        }60      }61      // console.log('exit loop');62    }63    64    //validate that the page has the same number of occurances to make sure we highlight the right one65    if (iOccuranceLength == colAncestorPosition.length)66    {67      return returnAncestor;          68    }69    else70    {71      return null;72    }73  },  74  75  addToVisibleShifts: function(shift){76    // console.log("===================================================addToVisibleShifts");77    var commonAncestor = this.getRangeAncestorNode(shift.range);78    79    var visibleShiftMeta = {80      sscutupid: shift.sscutupid,81      commonAncestor: commonAncestor82    }83    84    this.visibleShifts.push(visibleShiftMeta);85  },86  87  canShowShift: function(json){88    /*console.log("==================================================canShowShift json");*/89    if($chk(json.range)){90      var thisCommonAncestor = this.getRangeAncestorNode(json.range);91      92      for(var i=0; i<this.visibleShifts.length; i++){93        var thatCommonAncestor = this.visibleShifts[i].commonAncestor;94        95        if(thisCommonAncestor == thatCommonAncestor){96            alert("You are attempting to create a new Cutup that confilicts with " +97              "one currently being viewed on the page. Try hiding some of the currently displayed Cutups.");           98            return false;99        }100        101        var thisCommonAncestorElements =  $(thisCommonAncestor).getElements("*");102        var thatCommonAncestorElements =  $(thisCommonAncestor).getElements("*");103        104        for (var i=0; i<thisCommonAncestorElements.length; i++){105          for(var x=0; x<thatCommonAncestorElements.length; x++){106            if(thatCommonAncestorElements[x] == thisCommonAncestorElements[i]){107              alert("You are attempting to create a new Cutup that confilicts with " +108                "one currently being viewed on the page. Try hiding some of the currently displayed Cutups.");            109              return false;110            }111          }112        }113        for (var i=0; i<thatCommonAncestorElements.length; i++){114          for(var x=0; x<thisCommonAncestorElements.length; x++){115            if(thatCommonAncestorElements[i] == thisCommonAncestorElements[x]){116              alert("You are attempting to create a new Cutup that confilicts with " +117                "one currently being viewed on the page. Try hiding some of the currently displayed Cutups.");            118              return false;119            }120          }121        }122      }123    }124    return true;125  },126  127  wordPattern: new RegExp("(\\S+(\\s?)+){1,1}","g"), //default chunk is one 'word'128  129  buildUI: function(){130    var SSCutupWidget = new ShiftSpace.Element('div',{131      'id':'SSCutupWidget'});132    133    var SSCutupHandle = new ShiftSpace.Element('span',{134      'id':'SSCutupHandle'});135    136    var SSCutupTitleLabel = new ShiftSpace.Element('label',{137      'for':'SSCutupTitle'}).appendText('title:');138    139    var SSCutupTitle = new ShiftSpace.Element('input',{140      'id':'SSCutupTitle'141    });142    143    var SSCutupControls = new ShiftSpace.Element('div',{144      'id':'SSCutupControls'});145    146    var SSCutupChunkLabel = new ShiftSpace.Element('span',{147    'id':'SSCutupChunkLabel'});148    149    var SSCutupButtonSmaller = new ShiftSpace.Element('span',{150      'id':'SSCutupButtonSmaller'});151    152    var SSCutupButtonLarger = new ShiftSpace.Element('span',{153      'id':'SSCutupButtonLarger'});154    155    var SSCutupChunkAmount = new ShiftSpace.Element('span',{156      'id':'SSCutupChunkAmount'157    }).appendText("1");158    159    var SSCutupButtonCutup = new ShiftSpace.Element('span',{160      'id':'SSCutupButtonCutup'});161    162    var SSCutupButtonCancel = new ShiftSpace.Element('span',{163      'id':'SSCutupButtonCancel'});164    165    var SSCutupButtonSave = new ShiftSpace.Element('span',{166      'id':'SSCutupButtonSave'});167    168    var SSCutupButtonClose = new ShiftSpace.Element('span',{169      'id':'SSCutupButtonClose'});170    171    SSCutupControls.appendChild(SSCutupChunkLabel);172    SSCutupControls.appendChild(SSCutupButtonSmaller);173    SSCutupControls.appendChild(SSCutupChunkAmount);174    SSCutupControls.appendChild(SSCutupButtonLarger);175    SSCutupControls.appendChild(SSCutupButtonCutup);176    SSCutupControls.appendChild(SSCutupButtonCancel);177    SSCutupControls.appendChild(SSCutupButtonSave);178    SSCutupControls.appendChild(SSCutupButtonClose);179    180    SSCutupWidget.appendChild(SSCutupHandle);181    SSCutupWidget.appendChild(SSCutupTitleLabel);182    SSCutupWidget.appendChild(SSCutupTitle);183    SSCutupWidget.appendChild(SSCutupControls);184    185    SSCutupWidget.injectInside(document.body);186    187    SSCutupWidget.makeDraggable({'handle':SSCutupHandle});188    189    this.SSCutupWidget = SSCutupWidget;190    this.SSCutupTitle = SSCutupTitle;191    this.SSCutupChunkLabel = SSCutupChunkLabel;192    this.SSCutupButtonSmaller = SSCutupButtonSmaller;193    this.SSCutupButtonLarger = SSCutupButtonLarger;194    this.SSCutupChunkAmount = SSCutupChunkAmount;195    this.SSCutupButtonCutup = SSCutupButtonCutup;196    this.SSCutupButtonCancel = SSCutupButtonCancel;197    this.SSCutupButtonSave = SSCutupButtonSave;198    this.SSCutupButtonClose = SSCutupButtonClose;199    200    this.UIBuilt = true;201    202  },203  204  showInterface: function(){205    this.parent();206    if(this.UIBuilt == true){207      $("SSCutupWidget").removeClass('SSDisplayNone');208      $("SSCutupWidget").removeClass('SSHidden');209    }210  },211  212  hideInterface: function(){213  }214  215});216var CutupsShift = ShiftSpace.Shift.extend({217    setup: function(json){218      var space = this.getParentSpace();219      220      if(this.isNewShift() == false){ //if this is a previously created shift221        222        this.sscutupid = json.sscutupid;223        this.range = json.range;224        225        if(json.range.origText){226          this.range.origText = this.deTokenizeNewline(json.range.origText);227        }228        229        this.cutupTextArray = json.cutupTextArray;230        this.origTextArray = json.origTextArray;231        this.joinedTextArray = json.joinedTextArray;232        this.sscutupid = json.sscutupid;233        234        this.cutupTextOnPage = false;235        236        if(json.range.ancestorOrigTextContent){237          this.range.ancestorOrigTextContent = this.deTokenizeNewline(json.range.ancestorOrigTextContent);238        }239      }else if(this.isNewShift() == true){ //if this shift has just been created240        if(space.UIBuilt != true){241          space.buildUI();242        }243        this.sscutupid = this.create_sscutupid();244        this.cutupTextOnPage = false; //if shift has cut text245        //a new shift246        //attaches events to widget247        //creates a range from a valid selection248        //creates cutup from range249        //inserts into document250        //on save detaches events events from widget251      }252    },253    254    tokenizeNewline: function(text){255      var tokenizedText = text.replace(new RegExp("\\n","g"),"__newline__");  256      return tokenizedText;257    },258    259    deTokenizeNewline: function(text){260      var deTokenizedText = text.replace(new RegExp("__newline__","g"),"\n");261      return deTokenizedText;262    },263    264    show: function() {265      // console.log("===================================================Shift show");266      var space = this.getParentSpace();267      if(this.isNewShift() == false){268        if(space.canShowShift(this) == false){269          return false;270        }271      }272      //showing a just created shift or a previously created and saved shift273      if(this.cutupTextOnPage == false){274        275        if (this.range) {276          if(space.canShowShift(this) == false){277            return false;278          }else{279            space.addToVisibleShifts(this);280          }281          //if origText exits clean it282          if(this.range.origText){283            this.range.origText = this.deTokenizeNewline(this.range.origText);284          }285          //if ancestorOrigTextContent exists clean it286          if(this.range.ancestorOrigTextContent){287            this.range.ancestorOrigTextContent = this.deTokenizeNewline(this.range.ancestorOrigTextContent);288          }289          this.turnOnRangeRef(this.range);290        }291        292      }293      if(this.isNewShift() == true){294        this.attachWidgetButtonEvents()295        296        //give UI feedback on active buttons297        space.SSCutupButtonCancel.addClass("inactive");298        space.SSCutupButtonSave.addClass("inactive");299        space.SSCutupButtonSmaller.removeClass("inactive");300        space.SSCutupButtonLarger.removeClass("inactive");301      }302      //scroll to cutup303      window.location.hash = this.getId();304      //FX for fading Cutup background-color alpha to transparent305      function fadeToTrans(){306        var trans = 1.0;307        function fade(){308          if(trans > 0.2){       309            trans = trans - 0.1;310            $$('span.SSCut').setStyle('outline','thin solid rgba(167,8,4,' + trans + ')');311            setTimeout(fade,50);312          }else{313            $$('.SSCut').setStyle('outline','');314          }315        }316        return fade();317      }318      fadeToTrans();319    },320    321    encode: function(){322      var space = this.getParentSpace();323      324      this.summary = space.SSCutupTitle.value;325      326      //remove title value after save and set button from re-cut to cutup327      space.SSCutupTitle.value = "";328      space.SSCutupButtonCutup.setStyle('background-position','center 0px');329      330      this.range.origText = this.tokenizeNewline(this.range.origText);331      332      if(this.range.ancestorOrigTextContent){333        this.range.ancestorOrigTextContent = this.tokenizeNewline(this.range.ancestorOrigTextContent);334      }335      //this.range.ancestorOrigTextContent = "REMOVED ANCESTOR ORIGINAL TEXT";336      return {337        sscutupid: this.sscutupid,338        range: this.range,339        cutupTextArray: this.cutupTextArray,340        origTextArray: this.origTextArray,341        joinedTextArray: this.joinedTextArray,342        summary: this.summary343      }344    },345    346    create_sscutupid: function(){347      var now = new Date();348      var month = now.getMonth() + 1;349      var day = now.getDate();350      var year = now.getFullYear();351      var hour = now.getHours();352      var min = now.getMinutes();353      var sec = now.getSeconds();354      var rand = $random(0,1000000);355      return (month + "-" + day + "-" + year + "-" + hour + "-" + min + "-" + sec + "-" + rand);356    },357    358    detachWidgetButtonEvents: function(){359      var space = this.getParentSpace();360      361      space.SSCutupButtonCutup.removeEvents("mousedown");362      space.SSCutupButtonSave.removeEvents("mousedown");363      space.SSCutupButtonCancel.removeEvents("mousedown");364      space.SSCutupButtonClose.removeEvents("mousedown");365      space.SSCutupButtonLarger.removeEvents("mousedown");366      space.SSCutupButtonSmaller.removeEvents("mousedown");367    },368    369    attachWidgetButtonEvents: function(){370      var space = this.getParentSpace();371      var self = this;372      space.SSCutupChunkAmount.setText("1");//reset chunk amount gui display to 1373      space.SSCutupButtonCutup.addEvent("mousedown",function(){374          self.fireCutup(); 375      });376      377      space.SSCutupButtonSave.addEvent("mousedown",function(){378          379          if(self.cutupTextOnPage == false){380            return false;381          }382          383          if(space.SSCutupTitle.value.match(/\S+/) == null){384            alert("You must give your Cutup a title before saving");385            return false;386          }387          388          self.detachWidgetButtonEvents();389          /*space.addToVisibleShifts(self);*/390          space.allocateNewShift();391          self.save();392      });393      394      space.SSCutupButtonCancel.addEvent("mousedown",function(){395          self.cancelCutup();396          space.SSCutupButtonCancel.addClass("inactive");397          space.SSCutupButtonSave.addClass("inactive");398          399          space.SSCutupButtonLarger.removeClass("inactive");400          space.SSCutupButtonSmaller.removeClass("inactive");401      });402      403      space.SSCutupButtonClose.addEvent("mousedown",function(){404         self.closeWidget();405         self.detachWidgetButtonEvents();406         space.SSCutupWidget.addClass("SSDisplayNone");407         space.SSCutupWidget.addClass("SSHidden");408      });409      410      space.SSCutupButtonLarger.addEvent("mousedown",function(){411          self.incrementChunkAmount();412      });413      414      space.SSCutupButtonSmaller.addEvent("mousedown",function(){415          self.decrementChunkAmount();416      });417      418    },419    420    incrementChunkAmount: function(){421      var space = this.getParentSpace();422      var self = this;423      var amount = parseInt(space.SSCutupChunkAmount.getText());424      425      if(self.cutupTextOnPage == true){426        alert("You cannot change the word chunk amount after a Cutup has been created.");427        return false;428      }429      430      if(amount < 20){431        amount = amount + 1;432        space.SSCutupChunkAmount.setText(amount);433      }else{434        amount = 1;435        space.SSCutupChunkAmount.setText(amount);436      }437      this.setWordChunkSize(amount);438    },    439    440    decrementChunkAmount: function(){441      var space = this.getParentSpace();442      var self = this;443      var amount = parseInt(space.SSCutupChunkAmount.getText());444      445      if(self.cutupTextOnPage == true){446        alert("You cannot change the word chunk amount after a Cutup has been created.");447        return false;448      }      449      450      if(amount > 1){451        amount = amount - 1;452        space.SSCutupChunkAmount.setText(amount);453      }else{454        amount = 20;455        space.SSCutupChunkAmount.setText(amount);456      }457      458      this.setWordChunkSize(amount);459    },460    461    cancelCutup: function(){462      var space = this.getParentSpace();463      //cancel is to be used during the creation of a shift nowhere else as will464      //cause ConFrusions465      if(this.cutupTextOnPage == false) return false;466      //ignores the specific shift since only one cutup can be on at a given moment 467      //search for all span elements with _shiftspace_cutup attribute and open them468      var xPathResult = document.evaluate(".//span[@sscutupid='" + this.sscutupid + "']", document, null,469          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);470      471      var parentNodes = [];472      for (var i=0,l=0; i < xPathResult.snapshotLength; i++) {473          var spanElement = xPathResult.snapshotItem(i);474          //if is not an empty node grab content from json475          if(!xPathResult.snapshotItem(i).textContent.match(/^\s+$/) && this.isValidCutupTextNode(xPathResult.snapshotItem(i))){476            var newTextNode = document.createTextNode(this.origTextArray[l]);477            l++;478          }else{479            var newTextNode = document.createTextNode(spanElement.textContent);480          }481          parentNodes[i] = spanElement.parentNode;482          spanElement.parentNode.replaceChild(newTextNode, spanElement);483      } 484      for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) {485          parentNodes[i].normalize();486      } 487      space.removeFromVisibleShifts(this.sscutupid);488      489      this.joinedTextArray = null;490      this.origTextArray = null;491      this.cutupTextArray = null;492      this.cutupTextOnPage = false;493      494      space.SSCutupButtonCutup.setStyle('background-position','center 0px');495        496    },497    498    closeWidget: function(){499      var self = this;500      var space = this.getParentSpace();501      self.cancelCutup();502    },503    hideCutups: function(json) {504        var xPathResult = document.evaluate(".//span[@sscutupid='" + json.sscutupid + "']", document, null,505            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);506        507        var parentNodes = [];508        for (var i=0,l=0; i < xPathResult.snapshotLength; i++) {509          //if is not an empty node grab content from json510          var spanElement = xPathResult.snapshotItem(i);511          if(!xPathResult.snapshotItem(i).textContent.match(/^\s+$/) && this.isValidCutupTextNode(xPathResult.snapshotItem(i))){512            var newTextNode = document.createTextNode(json.range['origArray'][l]);513            l++;514          }else{515            var newTextNode = document.createTextNode(spanElement.textContent);516          }517          parentNodes[i] = spanElement.parentNode;518          spanElement.parentNode.replaceChild(newTextNode, spanElement);519        } 520  521        for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) {522            parentNodes[i].normalize();523        } 524    },     525    526    hide: function(){527      // console.log("=================================================Shift hide");528      space = this.getParentSpace();529      var space = this.getParentSpace();530      531      this.hideCutups(this);532      this.cutupTextOnPage = false;533      space.removeFromVisibleShifts(this.sscutupid);534    },535    536    setWordChunkSize: function(numOfWords){537      var pattern = "(\\S+(\\s?)+){1," + numOfWords + "}";538      this.wordPattern = new RegExp(pattern,"g");539    },540    541    wordPattern: new RegExp("(\\S+(\\s?)+){1,1}","g"),542    543    fireCutup: function(){544      var space = this.getParentSpace();545      var self = this;546      //if selection exists and there is no an unsaved cutup on the page547      if (!window.getSelection().getRangeAt(0).collapsed && this.cutupTextOnPage == false) {548        549         var newRangeRef = ShiftSpace.RangeCoder.toRef(window.getSelection().getRangeAt(0));550         //if this newRangeRef conflicts with on currently show dont create551         552         this.range = newRangeRef;553         554         if(space.canShowShift(this) == false){555           return false;556         }  557         //this.tempCommonAncestor = space.getRangeAncestorNode(this)558         space.addToVisibleShifts(this);559         this.turnOnRangeRef(newRangeRef);560         561          //cutupTextArray contains text in selected range 'cutup'562          newRangeRef.cutupsArray = this.cutupTextArray;563          564          //origTextArray contains original text selected565          newRangeRef.origArray = this.origTextArray;566          567          //give UI feedback for re-cut568          space.SSCutupButtonCutup.setStyle('background-position','center -60px');569          570          this.cutupTextOnPage = true;571          572      }else if(this.cutupTextOnPage == true){573        //origTextArray exists so just re-cutup current cutup574          var xPathQuery = "//*[@sscutupid='"  + this.sscutupid + "']";575          var xPathResult = document.evaluate(xPathQuery, document.body, null,576              XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);577          this.cutupRange(xPathResult);578      }else{579        return false;580      }581      582      //give UI feedback583      space.SSCutupButtonCancel.removeClass("inactive");584      space.SSCutupButtonSave.removeClass("inactive");585      space.SSCutupButtonLarger.addClass("inactive");586      space.SSCutupButtonSmaller.addClass("inactive");587      588      return false;589    },590    591    surroundTextNode: function(oNode, objRange, surroundingNode){592        var tempRange;593        //if this selection starts and ends in the same node594        if((oNode==objRange.startContainer)&&(oNode==objRange.endContainer)) {595            objRange.surroundContents(surroundingNode);596        }597        else598        {599            if(objRange.isPointInRange(oNode,1) || oNode==objRange.startContainer)600            {601                //check if the node is in the middle of the selection 602                if((oNode!=objRange.startContainer)&&(oNode!=objRange.endContainer))//surround the whole node603                {604                    surroundingNode.textContent = oNode.textContent;605                    oNode.parentNode.replaceChild(surroundingNode, oNode);606                }607                else //if start at suppply surround text from start point to end608                if(oNode==objRange.startContainer)//surround the node from the start point609                {610                    tempRange = document.createRange();611                    tempRange.setStart(oNode, objRange.startOffset);612                    tempRange.setEnd(oNode, oNode.textContent.length);613                    tempRange.surroundContents(surroundingNode);614                }615                else      //if endAt supply surround text node from 0 to End location 616                if(oNode==objRange.endContainer)//surround the node from the start point617                {618                    tempRange = document.createRange();619                    tempRange.setStart(oNode, 0);620                    tempRange.setEnd(oNode, objRange.endOffset);621                    tempRange.surroundContents(surroundingNode);622                }623            }624        }        625    },   626    627    turnOnRangeRef: function(ref) {628      // console.log("=======================================turnOnRangeRef");629      var self = this;630      631      var range = ShiftSpace.RangeCoder.toRange(ref);632      var objAncestor = range.commonAncestorContainer;633      634      if (objAncestor.nodeType == 3) // text node635          objAncestor = objAncestor.parentNode;636        637      var xPathResult = document.evaluate(".//text()", objAncestor, null,638          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);        639      // iteratate on all the text nodes in the document and mark if they are in the selection range640      for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) {641          // we need clean styles so we don't use ShiftSpace.Element642          var enclosingSpan = document.createElement("span");643          enclosingSpan.id = this.getId();644          645          enclosingSpan.setAttribute("sscutupid",this.sscutupid);646          enclosingSpan.setAttribute("class","SSCutup");647          this.surroundTextNode(xPathResult.snapshotItem(i), range, enclosingSpan);648      }649      //if cutUpArray does not exist call cutupRange on xPathResult of cutups span650      if(!this.cutupTextArray){651        var xPathQuery = "//*[@sscutupid='"  + this.sscutupid + "']";652        var xPathResult2 = document.evaluate(xPathQuery, objAncestor, null,653            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);654        //iterate through snapshot & rewrite textnodes655        this.cutupRange(xPathResult2);656      }else{657        var xPathQuery = "//*[@sscutupid='"  + this.sscutupid + "']";658        var xPathResult2 = document.evaluate(xPathQuery, objAncestor, null,659            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);660        //reinsert sorted array as string back into document661        for ( var i=0,l=0; i < xPathResult2.snapshotLength; i++ ){662          //if node is not empty and nodes parent is not a script tag663          if(!xPathResult2.snapshotItem(i).textContent.match(/^\s+$/) && this.isValidCutupTextNode(xPathResult2.snapshotItem(i))){664            $(xPathResult2.snapshotItem(i)).setHTML(ref.cutupsArray[l].join(""));665            l++666          }667        }668      }669    },670    cutupRange: function(xPathResult){671      var space = this.getParentSpace();672      673      if(this.cutupTextOnPage == false){674        //if there is no unsaved cutup on page then create new arrays to hold text 675        //otherwise use those current676        this.cutupTextArray = Array();  //contains cutup text nodes677        this.origTextArray = Array();   //contains precutup orig text nodes678        this.joinedTextArray = Array();   //contains text from all text nodes split into single array679        //break up snapshot into arrays of words680        for ( var i=0 ; i < xPathResult.snapshotLength; i++ ){681            if(this.isValidCutupTextNode(xPathResult.snapshotItem(i))){682              var text = xPathResult.snapshotItem(i).textContent;683              var lineArray = text.match(this.wordPattern);684              //joinedTextArray contains all arrays of words from text nodes in a single array.685              this.joinedTextArray = this.joinedTextArray.concat(lineArray);686              //do not add empty nodes to array or is content is javascript687              if(lineArray != null){ 688                this.cutupTextArray.push(lineArray); //push array of words into cutupTextArray689                this.origTextArray.push(text);  //push original text into origTextArray690              }691            }692        }693        //filter out null values and SCRIPT content694        this.joinedTextArray = this.joinedTextArray.filter(function(item,index){695            return item != null;696        });697      }698      //randomly sort joined arrays 699      this.joinedTextArray.sort(function(a,b){700          return Math.random() - 0.5;701      });702      //break up reinsert sorted item into multiline array703      //this keeps the same number of words in each node704      //while the actual words change (if 1 word chunks are selected)705      var i = 0;706      var chunkPattern = new RegExp("((\\s?\\S+)+)(\\s$)?");707      //wrap word 'chunks' in span tags708      for(var arr=0; arr<this.cutupTextArray.length; arr++){709          for(var arrItem=0; arrItem<this.cutupTextArray[arr].length; arrItem++){710              this.cutupTextArray[arr][arrItem] = this.joinedTextArray[i].replace(chunkPattern," <span class=\"SSCut\">$1</span> ");711              i++;712          }713      }714      //reinsert sorted array as string back into document715      for(var i=0,l=0; i < xPathResult.snapshotLength; i++){716        //if node is not empty717        if(!xPathResult.snapshotItem(i).textContent.match(/^\s+$/) && this.isValidCutupTextNode(xPathResult.snapshotItem(i))){718          //word chunk spans inserted with regex so must use setHTML719          if($chk(this.cutupTextArray[l])){720            $(xPathResult.snapshotItem(i)).setHTML(this.cutupTextArray[l].join(""));721            l++722          }else{723            break;724          }725        }726      } 727      //FX for fading Cutup background-color to transparent728      var sscutupid = this.sscutupid;729      function fadeToTrans(){730        snapshotNodes = document.evaluate(".//span[@sscutupid='" + sscutupid + "']", document, null,731          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);732        var trans = 1.0;733        function fade(){734          if(trans > 0.2){       735            trans = trans - 0.1;736            $ES('span.SSCut',snapshotNodes.snapshotItem(i)).setStyle('outline','thin solid rgba(167,8,4,' + trans + ')');737            setTimeout(fade,50);738          }739          else740          {741            // restore original element style742            $$('.SSCut').setStyle('outline','');743          }744        }745        return fade();746      }747      fadeToTrans();748    },749    750    isValidCutupTextNode: function(node){751     return ($(node) != null && $(node) != undefined && $(node).getParent().nodeName != "SCRIPT"); 752    }753      754});755// One of the most striking signs of the decay of art is when we see its 756// separate forms jumbled together.757// -Geothe...utils.js
Source:utils.js  
...227export function exportToJSON(vc) {228    console.warn(229        "VideoContext.exportToJSON has been deprecated. Please use VideoContext.snapshot instead."230    );231    return JSON.stringify(snapshotNodes(vc));232}233export function snapshot(vc) {234    return {235        nodes: snapshotNodes(vc),236        videoContext: snapshotVideoContext(vc)237    };238}239function snapshotVideoContext(vc) {240    return {241        currentTime: vc.currentTime,242        duration: vc.duration,243        state: vc.state,244        playbackRate: vc.playbackRate245    };246}247let warningExportSourceLogged = false;248function snapshotNodes(vc) {249    function qualifyURL(url) {250        var a = document.createElement("a");251        a.href = url;252        return a.href;253    }254    function getInputIDs(node, vc) {255        let inputs = [];256        for (let input of node.inputs) {257            if (input === undefined) continue;258            let inputID;259            let inputIndex = node.inputs.indexOf(input);260            let index = vc._processingNodes.indexOf(input);261            if (index > -1) {262                inputID = "processor" + index;...camadia.user.js
Source:camadia.user.js  
...124    }125126    function availableHeals() {127        let heals = []128        let usables = snapshotNodes( '//div[contains(@class, "isusuable")]' )129        for ( let i = 0; i < usables.snapshotLength; i++ ) {130            let usable = usables.snapshotItem( i )131            let title = usable.title132            if ( title.indexOf( ' : Heals ' ) === -1 ) continue133            let count = parseInt( stringValue( 'span[@class="item_invent_count"]', usable ) )134            if ( count === 0 ) continue135            usable.style.border = '1px solid #0a0'136            title = usable.title.split( ' : Heals ' )137            heals.push( { title: usable.title, amount: parseInt( title[ 1 ].trim() ), count: count, node: usable } )138        }139        return heals140    }141142    function autoEat() {143        let HP = playerHP()144        if ( !HP || HP.remaining === HP.total ) return145        let heals = availableHeals()146        for ( let i = 0; i < heals.length; i++ ) {147            let heal = heals[ i ]148            if ( HP.total - HP.remaining < heal.amount ) continue149            click( null, heal.node, () => {150                let heals = availableHeals()151                let total = 0152                for ( let i = 0; i < heals.length; i++ ) total += heals[ i ].amount * heals[ i ].count153                HP = playerHP()154                log( 'Your HP was at ' + HP.remaining + '/' + HP.total + '. You ate ' + heal.title.split( ' :' )[ 0 ] + ' which healed for +' + heal.amount + ' (+' + total + ' heals remaining)' )155                log( 'You are healing at a rate of ' + healPerMin() + ' heals/min' )156            } )157            break158        }159    }160161    function autoCombat() {162        let leavecombat = singleNode( '//a[@id="leavecombat"]' )163        if ( !leavecombat ) return164        let combatTraining = singleNode( '//select[@id="combat-training"]' )165        if ( !combatTraining ) return166        if ( !autoCombat.trainingRegistered ) {167            combatTraining.addEventListener( 'change', () => { changeCombatTraining( 0 ) } )168            autoCombat.trainingRegistered = true169        }170        if ( availableHeals().length === 0 ) return click( 'No heals available, leaving combat', leavecombat )171        leavecombat.style.visibility = 'visible'172        let xpath = '//a[@id="fightagain" and @style="visibility: visible;"]'173        let fightagain = singleNode( xpath )174        if ( fightagain ) click( stringValue( '//div[@id="finishmsg"]/p[1]' ), xpath, () => {175            log( 'You are earning ' + xpPerMin() + ' XP/min' )176            let training = 'Training '177            let nodes = snapshotNodes( '//div[@id="combat_screen"]/p[3]//text()' )178            for ( let i = 0; i < nodes.snapshotLength; i++ ) training += nodes.snapshotItem( i ).textContent179            log( training )180        } )181    }182183    function xpPerMin( period ) {184        period = period || 600185        let messages = historyFind( /you earned (\d+) [a-z]+ experience/gi, period )186        let gains = 0187        for ( let i = 0; i < messages.length; i++ ) {188            let message = messages[ i ]189            let match = /you earned (\d+) [a-z]+ experience/gi.exec( message.text )190            if ( match ) gains += parseInt( match[ 1 ] )191        }192        return ( 60 * gains / period ).toFixed( 1 )193    }194195    function healPerMin( period ) {196        period = period || 600197        let messages = historyFind( /you ate [a-z ]+ which healed for \+(\d+) /gi, period )198        let heals = 0199        for ( let i = 0; i < messages.length; i++ ) {200            let message = messages[ i ]201            let match = /you ate [a-z ]+ which healed for \+(\d+) /gi.exec( message.text )202            if ( match ) heals += parseInt( match[ 1 ] )203        }204        return ( 60 * heals / period ).toFixed( 1 )205    }206207    function handleNotifications() {208        let notifybox = singleNode( '//div[@id="notify_player_box"]' )209        if ( !notifybox || notifybox.style.display === '' || notifybox.style.display === 'none' ) return210        let notify = stringValue( '//div[@id="notify_msg"]' ).trim()211        if ( notify === '' ) return212        click( notify, '//button[@id="close_notify_player_box"]', () => {213            if ( notify.indexOf( ' level has increased to ' ) > -1 ) changeCombatTraining( 1 )214        } )215    }216217    function changeCombatTraining( delta ) {218        let combatTraining = singleNode( '//select[@id="combat-training"]' )219        if ( !combatTraining ) return220        let index = combatTraining.options.selectedIndex221        if ( index + delta >= combatTraining.options.length ) index = index - combatTraining.options.length222        else if ( index + delta < 0 ) index = index + combatTraining.options.length223        combatTraining.options.selectedIndex = index + delta224        click( null, singleNode( '//button[@id="change-skill"]' ), () => {225            log( 'Now training ' + combatTraining.options[ combatTraining.options.selectedIndex ].text )226        } )227    }228229    function debounce( func, delay ) {230        let inDebounce231        return function () {232            const context = this233            const args = arguments234            if ( inDebounce ) return235            clearTimeout( inDebounce )236            inDebounce = setTimeout( () => {237                inDebounce = null238                args[ 0 ] && log( args[ 0 ] )239                func.apply( context, args )240            }, delay )241        }242    }243244    const click = debounce( ( debug, node_or_xpath, callback ) => {245        if ( typeof node_or_xpath === 'string' ) node_or_xpath = singleNode( node_or_xpath )246        if ( !node_or_xpath ) return247        node_or_xpath.click()248        callback && callback()249    }, 500 )250251    function simulateKeyPress( node_or_xpath, keys ) {252        if ( typeof node_or_xpath === 'string' ) node_or_xpath = singleNode( node_or_xpath )253        if ( !node_or_xpath ) return254        let keypressListener = e => { e.target.value += e.key }255        node_or_xpath.addEventListener( 'keypress', keypressListener )256        node_or_xpath.focus()257        keys.split( '' ).forEach( key => {258            const e = new window.KeyboardEvent( 'keypress', {259                bubbles: true,260                key: key,261                keyCode: key.charCodeAt( 0 ),262                charCode: key.charCodeAt( 0 ),263            } )264            document.activeElement.dispatchEvent( e )265        } )266        node_or_xpath.removeEventListener( 'keypress', keypressListener )267    }268269    function simulateKeyUp( keys ) {270        keys.split( '' ).forEach( key => {271            const e = new window.KeyboardEvent( 'keypress', {272                bubbles: true,273                key: key,274                keyCode: key.charCodeAt( 0 ),275                charCode: key.charCodeAt( 0 ),276            } )277            document.activeElement.dispatchEvent( e )278        } )279    }280281    function simulateKeyDown( keys ) {282        keys.split( '' ).forEach( key => {283            console.log( key )284            const e = new window.KeyboardEvent( 'keypress', {285                bubbles: true,286                key: key,287                keyCode: key.charCodeAt( 0 ),288                charCode: key.charCodeAt( 0 ),289            } )290            document.activeElement.dispatchEvent( e )291        } )292    }293294    function post( url, success ) {295        $.ajax( {296            type: 'POST', url: url, success: data => {297                if ( isJson( data ) ) return success( data )298                let node = document.createElement( 'div' )299                node.innerHTML = data300                success( node )301            }302        } )303    }304305    function isJson( item ) {306        item = typeof item !== "string" ? JSON.stringify( item ) : item307        try { item = JSON.parse( item ) } catch ( e ) { return false }308        return typeof item === "object" && item !== null309    }310311    function stringValue( xpath, context ) {312        return document.evaluate( xpath, context || document, null, XPathResult.STRING_TYPE, null ).stringValue313    }314315    function singleNode( xpath, context ) {316        return document.evaluate( xpath, context || document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue317    }318319    function snapshotNodes( xpath, context ) {320        return document.evaluate( xpath, context || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null )321    }322323    function log( msg ) {324        let message = { timestamp: timestamp(), text: msg.trim() }325        console.log( '%c' + message.timestamp + ' %c' + message.text, 'color:#444', 'color:#777' )326        history = localStorage.getItem( 'history' ) || '[]'327        try { history = JSON.parse( history ) } catch { history = [] }328        history.push( message )329        if ( MAX_HISTORY < history.length ) history.splice( 0, history.length - MAX_HISTORY )330        localStorage.setItem( 'history', JSON.stringify( history ) )331    }332333    function timestamp( date ) {
...armsofwar.user.js
Source:armsofwar.user.js  
...66        let amount = amountOfResource( resource )67        if ( donation === 'castleConscripts' ) donateAmount = 168        if ( amount < donateAmount ) return gatherResource( resource )69        return click( null, '//button[@id="donateType"]', null, () => {70            let donateTypes = snapshotNodes( '//div[@id="donateTypeDropDown"]/div' )71            for ( let i = 0; i < donateTypes.snapshotLength; i++ ) {72                let donateType = donateTypes.snapshotItem( i )73                if ( donateType.textContent === resource ) {74                    click( null, donateType, null, () => {75                        aow.donateNext = false76                        singleNode( '//input[@id="donationAmount"]' ).value = donateAmount77                        click( 'Donate ' + donateAmount + ' ' + resource, '//button[@id="donateBtn"]' )78                    } )79                    break80                }81            }82        } )83    }8485    function teamColour() {86        return stringValue( '//div[@id="battle-store-units-tab"]//div[@class="unit-store-image"][1]/img/@src' ).endsWith( 'Blue.png' ) ? 'Blue' : 'Red'87    }8889    function enemyTeamColour() {90        return teamColour() === 'Blue' ? 'Red' : 'Blue'91    }9293    function castleTier() {94        return integerValue( '//div[@id="castle' + teamColour() + '"]/span[@class="castleHealth"]/span[text()="Tier:"]/following-sibling::span[1]' )95    }9697    function enemyCastleTier() {98        return integerValue( '//div[@id="castle' + enemyTeamColour() + '"]/span[@class="castleHealth"]/span[text()="Tier:"]/following-sibling::span[1]' )99    }100101    function autoBuy() {102        let gold = integerValue( '//span[@id="gold-inventory"]/span[@class="rss-inventory-text"]' )103        let equipStoreCosts = snapshotNodes( '//span[@class="equip-store-cost"]' )104        for ( let i = 0; i < equipStoreCosts.snapshotLength; i++ ) {105            let equipStoreCost = equipStoreCosts.snapshotItem( i )106            let equipStoreCostAmount = parseInt( equipStoreCost.textContent.split( ' ' )[ 0 ] )107            if ( equipStoreCostAmount <= gold ) {108                let equipTitle = stringValue( './ancestor::div[@class="equip-store-tile"]/div[@class="equip-store-title"]', equipStoreCost )109                if ( equipTitle === 'Mortar and Pestle' ) break110                click( 'Buy ' + equipTitle + ' ' + equipStoreCostAmount + ' G', './ancestor::div[@class="equip-store-tile"]/button[@class="equip-store-purchase"]', equipStoreCost )111                break112            }113        }114115        let buyUnitType = 'Basic'116        let tier = castleTier()117        if ( tier > 1 ) buyUnitType = 'Heavy'118        let unitStore = singleNode( '//div[@class="unit-store-tile" and ./div/@class="unit-store-title" and contains(./div/text(),"' + buyUnitType + '")]' )119        if ( !unitStore ) return120        let items = snapshotNodes( './/div[@id="' + buyUnitType.toLowerCase() + '-cost-content"]//span[@class="unit-store-detail-val" and not(text()="0")]', unitStore )121        for ( let i = 0; i < items.snapshotLength; i++ ) {122            let item = items.snapshotItem( i )123            let cost = parseInt( item.textContent.replace( ',', '' ).trim() )124            let resource = stringValue( '../text()', item ).replace( ':', '' )125            if ( amountOfResource( resource ) < cost ) return gatherResource( resource )126        }127        log( 'Tier ' + tier + ' -> Buy ' + buyUnitType )128        aow.donateNext = true129        return click( null, './button[@class="unit-store-purchase"]', unitStore )130    }131132    function gatherResource( resource ) {133        resource = resource.trim().toLowerCase()134        let id = 'battle-rss-' + ( resource === 'conscripts' ? 'cons' : resource )135        let activeButton = singleNode( '//div[@id="' + id + '"]/button[not(contains(@class, "btn-disabled"))]' )136        if ( activeButton ) click( null, activeButton )137    }138139    function amountOfResource( resource ) {140        resource = resource.trim().toLowerCase()141        let id = resource === 'conscripts' ? 'cons-inventory' : resource + '-inventory'142        return integerValue( '//span[@id="' + id + '"]/span[@class="rss-inventory-text"]' )143    }144145    function debounce( func, delay ) {146        let inDebounce147        return function () {148            const context = this149            const args = arguments150            if ( inDebounce ) return151            clearTimeout( inDebounce )152            inDebounce = setTimeout( () => {153                inDebounce = null154                args[ 0 ] && log( args[ 0 ] )155                func.apply( context, args )156            }, delay )157        }158    }159160    const click = debounce( ( debug, node_or_xpath, context, callback ) => {161        if ( typeof node_or_xpath === 'string' ) node_or_xpath = singleNode( node_or_xpath, context )162        if ( !node_or_xpath || !available( node_or_xpath ) ) return163        node_or_xpath.click()164        callback && callback()165    }, 1000 )166167    function available( node ) {168        if ( !node || node.style.visibility === 'hidden' || node.style.display === 'none' || node.disabled ) return false169        return true170    }171172    function stringValue( xpath, context ) {173        return document.evaluate( xpath, context || document, null, XPathResult.STRING_TYPE, null ).stringValue174    }175176    function integerValue( xpath, context ) {177        return parseInt( stringValue( xpath, context ).replace( ',', '' ).trim() )178    }179180    function singleNode( xpath, context ) {181        return document.evaluate( xpath, context || document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue182    }183184    function snapshotNodes( xpath, context ) {185        return document.evaluate( xpath, context || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null )186    }187188    function log( msg ) {189        const MAX_HISTORY = 1000190        let message = { timestamp: timestamp(), text: msg.trim() }191        console.log( '%c' + message.timestamp + ' %c' + message.text, 'color:#444', 'color:#777' )192        aow.history.push( message )193        if ( MAX_HISTORY < aow.history.length ) aow.history.splice( 0, aow.history.length - MAX_HISTORY )194        localStorage.setItem( aow.gameId, JSON.stringify( aow.history ) )195    }196197    function printmsg( timestamp, text ) {198        console.log( '%c' + timestamp + ' %c' + text, 'color:#444', 'color:#777' )
...nodetest.js
Source:nodetest.js  
1(function(win, doc, m) {2	"use strict";3	var area = m.ref("SampleNodeInfomationArea"),4		sampleRoot = m.ref("SampleElementNodeContainer");5	var NODETYPECONST = {6		1 : "ELEMENT_NODE",7		3 : "TEXT_NODE",8		7 : "PROCESSING_INSTRUCTION_NODE",9		8 : "COMMENT_NODE",10		9 : "DOCUMENT_NODE",11		10 : "DOCUMENT_TYPE_NODE",12		11 : "DOCUMENT_FRAGMENT_NODE"13	};14	function pp(txt) {15		m.log(txt);16		m.println(area, txt);17	}18	function outputNodeInfomation(node) {19		if (!node) {20			return;21		}22		pp("**********************************");23		pp("id:" + node.id);24		pp("nodeName:" + node.nodeName);25		pp("nodeType:" + node.nodeType + ", This is " + NODETYPECONST[node.nodeType]);26		pp("nodeValue:" + node.nodeValue);27		pp("data:" + node.data);28		/**29		 * 親ãã¼ããElementã¾ãã¯Documentã®å ´åï¼ãã®åãã¼ãã®30		 * å
¨ã¦ã®textContentãè¿ãã¦ãããç¹å®ã®è¦ç´ ã®textContentã®ã¿ã31		 * åå¾ããããªãã°firstChild.nodeValueããå¾ãã»ããå®å
¨ãã32		 * ãã ãå¤é¨ã®ã©ã¤ãã©ãªã«firstChildã夿´ããã¦ããªããã¨ãåæã§ããã33		 */34		pp("textContent:" + node.textContent);35		/* textããå¤ãå¾ãããæã¯åãå¤ãtextContentãããå¾ãããã */36		pp("text:" + node.text);37		/**38		 * ownerDocumentã«ã¯DocumentFragmentãããã¥ã¡ã³ã追å åã®ãã¼ãã§ã39		 * HTMLDocumentãä¿æããã¦ãããnullã«ãªãã®ã¯document.ownerDocument40		 * ã ããããããªãã41		 */42		pp("ownerDocument:" + node.ownerDocument);43		if (node.hasChildNodes()) {44			for (var i = 0, len = node.childNodes.length; i < len; i++) {45				outputNodeInfomation(node.childNodes[i]);46			}47		}48	}49	function outputNodeContainerInfomation() {50		var sampleFragment = doc.createDocumentFragment();51		var sampleScript = doc.createElement("script");52		sampleScript.setAttribute("id", "SampleScriptNode");53		sampleScript.setAttribute("src", "dummy.js");54		outputNodeInfomation(sampleScript);55		/**56		 * DocumentFragmentã«appendChildãã¦ãDocumentFragmentã®57		 * textContentãnodeValueã«ä½ãè¨å®ãããããã§ã¯ãªãã58		 */59		sampleFragment.appendChild(sampleScript);60		outputNodeInfomation(sampleFragment);61		sampleRoot.appendChild(sampleFragment);62		outputNodeInfomation(sampleRoot);63		sampleRoot.removeChild(sampleScript);64	}65	function outputNodeEquality(node, otherNode) {66		if (node && otherNode) {67			var separator = " ... ";68			69			/**70			 * 屿§ãåãã¼ããçãããã°æ¯è¼å¯¾è±¡ã®ãã¼ããcloneNodeã®71			 * æ»ãå¤ã ã£ãã¨ãã¦ãNode::isEqualNodeã¯trueãè¿ãã72			 * å³ã¡çããã®åºæºãisSameNodeã==æ¼ç®åããç·©ãã73			 */74			pp(node.id + ":" + node.nodeName + " isEqualNode " +75				otherNode.id + ":" + otherNode.nodeName + separator +76				node.isEqualNode(otherNode));77			/** 78			 * Node::isSameNodeã¯æ¬å½ã«åããã¼ãã¨ã®æ¯è¼ã§ãªãéã79			 * trueãè¿ããªããæ¯è¼å¯¾è±¡ãcloneNodeã®æ»ãå¤ã§ãfalseã¨ãªãã80			 * ==æ¼ç®åã§æ¯è¼ããæãåãçµæã«ãªãã81			 * ãªãDOM level 4ã§Node::isSameNodeã¯åé¤ããã¦ããã 82			 * ãã ãIE11ã«ã¯å®è£
ããã¦ããã83			 */84			if(typeof node.isSameNode === "function"){85				pp(node.id + ":" + node.nodeName + " isSameNode " +86					otherNode.id + ":" + otherNode.nodeName + separator +87					node.isSameNode(otherNode));88			}89			/**90			 * ==æ¼ç®åã¨===æ¼ç®åã®çµæã¯å¸¸ã«çãããªãã91			 * (æé»ã®å夿ãçºçããªãããï¼)92			 */93			pp(node.id + ":" + node.nodeName + " == " +94				otherNode.id + ":" + otherNode.nodeName + separator +95				(node == otherNode));96			pp(node.id + ":" + node.nodeName + " === " +97				otherNode.id + ":" + otherNode.nodeName + separator +98				(node === otherNode));99		}100	}101	function outputNodeContainerEquality(root) {102		var children = root.childNodes;103		for (var i = 0, len = children.length; i < len; i++) {104			var node = children[i];105			if (node.hasChildNodes()) {106				outputNodeContainerEquality(node);107			} else {108				outputNodeEquality(node, node.nextSibling);109			}110		}111	}112	113	function checkNodeSize(){114		var ul = doc.querySelector("ul.nodelist-sample-list"),115			snapshotNodes = doc.querySelectorAll("ul.nodelist-sample-list li"),116			livedNodes = ul.getElementsByTagName("li");117		118		for(var i = 0, len = snapshotNodes.length; i < len; i++){119			snapshotNodes[i].parentNode.removeChild(snapshotNodes[i]);120		}121		122		return {123			snapshot : snapshotNodes.length,124			lived : livedNodes.length,125			toString : function(){126				return "snapshot NodeList length:" + 127					this.snapshot + ", lived NodeList length:" + this.lived;128			}129		};130	}131	132	(function () {133		m.addListener(m.ref("NodeOutputExecuter"), "click", outputNodeContainerInfomation);134		m.addListener(m.ref("NodeEqualityTestExecuter"), "click", function() {135			var container = m.ref("NodeEqualitySampleContainer");136			pp("***** ã³ã³ãã以ä¸ã®Nodeã®æ¯è¼ *****");137			outputNodeContainerEquality(container);138			139			var sampleNode = doc.createElement("span");140			sampleNode.id  = "SampleTestNode";141			var sampleChildNode = doc.createTextNode("SampleTestText");142			sampleNode.appendChild(sampleChildNode);143			pp("***** ãµã³ãã«ã®Nodeèªèº«ã¨æ¯è¼ *****");144			outputNodeEquality(sampleNode, sampleNode);145			pp("***** ãµã³ãã«ã®Nodeã®cloneNode(true)ã¨æ¯è¼ *****");146			var clonedTrueSampleNode = sampleNode.cloneNode(true);147			outputNodeEquality(sampleNode, clonedTrueSampleNode);148			pp("***** ãµã³ãã«ã®Nodeã®cloneNode(false)ã¨æ¯è¼ *****");149			var clonedFalseSampleNode = sampleNode.cloneNode(false);150			outputNodeEquality(sampleNode, clonedFalseSampleNode);151			pp("***** cloneNode(true)ã®idã夿´ãã¦æ¯è¼ *****");152			clonedTrueSampleNode.id = "Cloned" + clonedTrueSampleNode.id;153			outputNodeEquality(container, clonedTrueSampleNode);154		});155		156		var savedNodes;157		158		m.addListener(m.ref("sample-node-remover"), "click", function(){159			savedNodes = doc.querySelectorAll("ul.nodelist-sample-list li");160			var result = checkNodeSize();161			pp(result);162		}, false);163		164		m.addListener(m.ref("sample-node-resetter"), "click", function(){165			if(savedNodes){166				var ul = doc.querySelector("ul.nodelist-sample-list");167				m.appendChildAll(ul, savedNodes);168			}169		}, false);170		171		m.addListener(m.ref("node-result-clearer"), "click", function(){172			m.clear(area);173		}, false);174	}());...snapshotRenderer.js
Source:snapshotRenderer.js  
...45        if (Array.isArray(n[0])) {46          // Node reference.47          const referenceIndex = snapshotIndex - n[0][0];48          if (referenceIndex >= 0 && referenceIndex < snapshotIndex) {49            const nodes = snapshotNodes(this._snapshots[referenceIndex]);50            const nodeIndex = n[0][1];51            if (nodeIndex >= 0 && nodeIndex < nodes.length) n._string = visit(nodes[nodeIndex], referenceIndex);52          }53        } else if (typeof n[0] === 'string') {54          // Element node.55          const builder = [];56          builder.push('<', n[0]);57          for (const [attr, value] of Object.entries(n[1] || {})) builder.push(' ', attr, '="', escapeAttribute(value), '"');58          builder.push('>');59          for (let i = 2; i < n.length; i++) builder.push(visit(n[i], snapshotIndex));60          if (!autoClosing.has(n[0])) builder.push('</', n[0], '>');61          n._string = builder.join('');62        } else {63          // Why are we here? Let's not throw, just in case.64          n._string = '';65        }66      }67      return n._string;68    };69    const snapshot = this._snapshot;70    let html = visit(snapshot.html, this._index);71    if (!html) return {72      html: '',73      pageId: snapshot.pageId,74      frameId: snapshot.frameId,75      index: this._index76    };77    if (snapshot.doctype) html = `<!DOCTYPE ${snapshot.doctype}>` + html;78    html += `79      <style>*[__playwright_target__="${this.snapshotName}"] { background-color: #6fa8dc7f; }</style>80      <script>${snapshotScript()}</script>81    `;82    return {83      html,84      pageId: snapshot.pageId,85      frameId: snapshot.frameId,86      index: this._index87    };88  }89  resourceByUrl(url) {90    const snapshot = this._snapshot;91    let result; // First try locating exact resource belonging to this frame.92    for (const resource of this._resources) {93      if (resource.timestamp >= snapshot.timestamp) break;94      if (resource.frameId !== snapshot.frameId) continue;95      if (resource.url === url) {96        result = resource;97        break;98      }99    }100    if (!result) {101      // Then fall back to resource with this URL to account for memory cache.102      for (const resource of this._resources) {103        if (resource.timestamp >= snapshot.timestamp) break;104        if (resource.url === url) return resource;105      }106    }107    if (result) {108      // Patch override if necessary.109      for (const o of snapshot.resourceOverrides) {110        if (url === o.url && o.sha1) {111          result = { ...result,112            responseSha1: o.sha1113          };114          break;115        }116      }117    }118    return result;119  }120}121exports.SnapshotRenderer = SnapshotRenderer;122const autoClosing = new Set(['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR']);123const escaped = {124  '&': '&',125  '<': '<',126  '>': '>',127  '"': '"',128  '\'': '''129};130function escapeAttribute(s) {131  return s.replace(/[&<>"']/ug, char => escaped[char]);132}133function escapeText(s) {134  return s.replace(/[&<]/ug, char => escaped[char]);135}136function snapshotNodes(snapshot) {137  if (!snapshot._nodes) {138    const nodes = [];139    const visit = n => {140      if (typeof n === 'string') {141        nodes.push(n);142      } else if (typeof n[0] === 'string') {143        for (let i = 2; i < n.length; i++) visit(n[i]);144        nodes.push(n);145      }146    };147    visit(snapshot.html);148    snapshot._nodes = nodes;149  }150  return snapshot._nodes;...kingdombattles.user.js
Source:kingdombattles.user.js  
...117    function singleNode( xpath, context ) {118        return document.evaluate( xpath, context || document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue119    }120121    function snapshotNodes( xpath, context ) {122        return document.evaluate( xpath, context || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null )123    }124125    function log( msg ) {126        let message = { timestamp: timestamp(), text: msg.trim() }127        console.log( '%c' + message.timestamp + ' %c' + message.text, 'color:#444', 'color:#777' )128        history = localStorage.getItem( 'history' ) || '[]'129        try { history = JSON.parse( history ) } catch { history = [] }130        history.push( message )131        if ( MAX_HISTORY < history.length ) history.splice( 0, history.length - MAX_HISTORY )132        localStorage.setItem( 'history', JSON.stringify( history ) )133    }134135    function printmsg( timestamp, text ) {
...Using AI Code Generation
1const playwright = require('playwright');2const fs = require('fs');3(async () => {4  const browser = await playwright.chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const snapshot = await page._snapshotter().snapshotNodes();8  fs.writeFileSync('snapshot.json', JSON.stringify(snapshot, null, 2));9  await browser.close();10})();11{12  "frame": {13    "document": {14      "frame": {15        "document": {16          "frame": {17            "document": {18              "frame": {19                "document": {20                  "frame": {21                    "document": {22                      "frame": {23                        "document": {24                          "frame": {25                            "document": {26                              "frame": {27                                "document": {28                                  "frame": {Using AI Code Generation
1const playwright = require('playwright');2(async () => {3    const browser = await playwright.webkit.launch();4    const context = await browser.newContext();5    const page = await context.newPage();6    await page.snapshotNodes({path: 'test.png'});7    await browser.close();8})();9    at NodeImpl._assertBoundingBox (C:\Users\pooja10    at NodeImpl._assertBoundingBox (C:\Users\pooja11    at NodeImpl._assertBoundingBox (C:\Users\pooja12    at NodeImpl._assertBoundingBox (C:\Users\pooja13    at NodeImpl._assertBoundingBox (C:\Users\pooja14    at NodeImpl._assertBoundingBox (C:\Users\pooja15    at NodeImpl._assertBoundingBox (C:\Users\pooja16    at NodeImpl._assertBoundingBox (C:\Users\pooja17    at NodeImpl._assertBoundingBox (C:\Users\pooja18    at NodeImpl._assertBoundingBox (C:\Users\poojaUsing AI Code Generation
1const playwright = require('playwright');2(async () => {3  const browser = await playwright['chromium'].launch();4  const page = await browser.newPage();5  const snapshot = await page._delegate.snapshotNodes();6  console.log(snapshot);7  await browser.close();8})();9{10  'data': {11      {12          {13              {14                  {15                  }16              }17          }18      }19  }20}21import json22with open('output.json') as f:23  data = json.load(f)24print(json.dumps(data, indent=2))25{26  "data": {27      {Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  const snapshot = await page._delegate.snapshotNodes();6  console.log(snapshot);7  await browser.close();8})();9{10    {11        {12        }13    }14}Using AI Code Generation
1const playwright = require('playwright');2const snapshotNodes = require('playwright/lib/snapshot/snapshotNodes');3(async () => {4  const browser = await playwright.chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const snapshot = await snapshotNodes(page, 'body');8  console.log(snapshot);9  await browser.close();10})();11{ id: 'foo' }12[ { nodeType: 1, nodeName: 'div', attributes: { id: 'foo' }, childNodeIndexes: [ 1, 2 ] }, { nodeType: 1, nodeName: 'span', attributes: {}, childNodeIndexes: [ 3 ] }, { nodeType: 1, nodeName: 'div', attributes: { id: 'baz' }, childNodeIndexes: [] }, { nodeType: 3, nodeName: '#text', attributes: {}, textContent: 'bar', childNodeIndexes: [] } ]Using AI Code Generation
1const playwright = require('playwright');2(async () => {3  const browser = await playwright.chromium.launch({4  });5  const page = await browser.newPage();6  await page.waitForSelector('input[name="q"]');7  await page.fill('input[name="q"]', 'Playwright');8  await page.click('input[type="submit"]');9  await page.waitForSelector('h3');10  const snapshot = await page._delegate.snapshotNodes();11  console.log(snapshot);12  await browser.close();13})();14    at CDPSession.send (/home/ankit/Downloads/playwright/node_modules/playwright-core/lib/cjs/protocol/channels.js:51:13)15    at async DOMSnapshot._snapshot (/home/ankit/Downloads/playwright/node_modules/playwright-core/lib/cjs/domSnapshot.js:31:16)16    at async Page._snapshot (/home/ankit/Downloads/playwright/node_modules/playwright-core/lib/cjs/page.js:118:18)17    at async Page.snapshotNodes (/home/ankit/Downloads/playwright/node_modules/playwright-core/lib/cjs/page.js:112:16)18    at async Object.<anonymous> (/home/ankit/Downloads/playwright/test.js:16:27)Using AI Code Generation
1const {snapshotNodes} = require('playwright/lib/server/snapshot/snapshotter');2const {chromium} = require('playwright');3const fs = require('fs');4(async () => {5  const browser = await chromium.launch();6  const context = await browser.newContext();7  const page = await context.newPage();8  const snapshot = await snapshotNodes(page, page);9  fs.writeFileSync('snapshot.json', JSON.stringify(snapshot, null, 2));10  await browser.close();11})();12{13  "attributes": {14  },15    {16        {17          "attributes": {18          }19        },20        {21          "attributes": {22          }23        },24        {25          "attributes": {26          }27        },28        {29          "attributes": {30          }31        },32        {33          "attributes": {34          }35        },36        {37          "attributes": {38          }39        },40        {41          "attributes": {42          }43        },44        {45          "attributes": {46          }47        },48        {49          "attributes": {50          }51        },Using AI Code Generation
1const playwright = require('playwright');2const fs = require('fs');3const path = require('path');4(async () => {5  for (const browserType of BROWSER) {6    const browser = await playwright[browserType].launch();7    const context = await browser.newContext();8    const page = await context.newPage();9    const snapshot = await page._client.send('DOM.snapshot', {10    });11    const snapshotString = JSON.stringify(snapshot);12    fs.writeFileSync(path.join(__dirname, 'snapshot.json'), snapshotString);13    await browser.close();14  }15})();Using AI Code Generation
1const playwright = require('playwright');2const fs = require('fs');3(async () => {4  for (const browserType of ['chromium', 'firefox', 'webkit']) {5    const browser = await playwright[browserType].launch();6    const context = await browser.newContext();7    const page = await context.newPage();8    const snapshot = await page._delegate._pageProxy._connection._session.send('DOM.snapshot', { computedStyles: ['*'] });9    fs.writeFileSync(`snapshot-${browserType}.json`, JSON.stringify(snapshot));10    await browser.close();11  }12})();13{14  "root": {15      {16        "importedDocument": null,17          {18            "importedDocument": null,19          },20          {LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
