userscript to remove elements with querySelectorAll fails - why? [duplicate] - userscripts

This question already has an answer here:
How to use greasemonkey to selectively remove content from a website
(1 answer)
Closed 4 years ago.
The goal is to remove (not hide) all HTML elements based on a match to their name or class with a userscript. Here is a portion of the userscript in question. It doesn't remove the elements. What should be changed?
// ==UserScript==
// #name Clean Giveaway sites
// #version 1.0
// #namespace namespace
// #description Remove junk from giveaway sites
// #include http://udemy.com/*
// #include http://udemyar.com/*
// #include http://www.udemy.com/*
// #include http://www.udemyar.com/*
// #include https://udemy.com/*
// #include https://udemyar.com/*
// #include https://www.udemy.com/*
// #include https://www.udemyar.com/*
// #grant none
// ==/UserScript==
var killit = document.querySelectorAll('c_header__left');
if (killit[0]) {
killit[0].parentNode.removeChild(killit[0]);
}
var killit = document.querySelectorAll('c_header__right');
if (killit[0]) {
killit[0].parentNode.removeChild(killit[0]);
}
var killit = document.querySelectorAll('more-from-instructor ud-react-loader ud-component--more-courses-by-instructor--app ud-react-loaded');
if (killit[0]) {
killit[0].parentNode.removeChild(killit[0]);
}

Are you looking for tags ? Because that's what you're asking querySelectorAll to fetch. Basicly if you have <c_header__left>...</c_header__left> in your code, querySelectorAll('c_header__left') should find it.
I assume you are looking for elements with the class c_header__left and in that cas you must prepend the string with a point.
The string you pass to querySelector and querySelectorAll has the same syntax for finding items as CSS
More clarity
Try
var killit = document.querySelectorAll('.c_header__left');

Related

Most efficient way of getting large std::vector into Swift?

I have an Objective-C class that populates a std:vector with millions of points. The structure of the vector is:
typedef std::vector<CGPoint> CGContour;
typedef std::vector<CGContour> CGContours;
So a CGContour is a vector of CGPoints and CGContours is a vector of the CGContour vector.
I need to access this data in a Swift class somehow. I don't want to use an NSArray because it has a huge overhead compared to using vector (it is like 10x as big and slow).
What would be the most efficient way to get millions of CGPoints accessible in Swift from my Objective-C class?
Edit:
I am populating my CGContours vector like this:
contourVector = CGContours(contours.size());
populatedContourNum = 0
//contours is OpenCV's contours
for( long c = 0; c < contours.size(); c++) {
if (populatedContourNum >= contourVector.size()) {
contourVector.resize(contourVector.size() + 1);
}
contourVector[populatedContourNum] = CGContour(contours[c].size());
for( long pointNum = 0; pointNum < contours[c].size(); pointNum++ )
{
contourVector[populatedContourNum][pointNum] = CGPointMake(contours[c][pointNum].x * scale,
contours[c][pointNum].y * scale);
}
populatedContourNum++;
}
Some parts are not clear enough but I will try to show you some example.
First of all, you need to prepare a class which can access your contourVector. (I cannot see if it is an instance field or a global variable, if it is an instance field, you may use the existing class.)
Create a header for the prepared class, again you may utilize the existing header, but this header needs to be compiled both in C-context and in C++ context. So, if your existing header contains some declaration which cannot be compiled in C-context, you may need separated two headers or some #ifs.
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#interface YourClass : NSObject
- (NSInteger)contoursSize;
- (NSInteger)contourSizeAtIndex:(NSInteger)index;
- (CGPoint *)contourAtIndex:(NSInteger)index;
//...
#end
NS_ASSUME_NONNULL_END
Then add 3 methods to the class specified in the header:
#import "YourClass.h"
#import <vector>
typedef std::vector<CGPoint> CGContour;
typedef std::vector<CGContour> CGContours;
static CGContours contourVector;
#implementation YourClass
- (NSInteger)contoursSize {
return contourVector.size();
}
- (NSInteger)contourSizeAtIndex:(NSInteger)index {
return contourVector[index].size();
}
- (CGPoint *)contourAtIndex:(NSInteger)index {
return contourVector[index].data();
}
#end
Please do not forget to include the header inside your Project-Bridging-Header.h:
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "YourClass.h"
You need to create a Swift side wrapper class, as you cannot create UnsafeBufferPointer in Objective-C.
class YourClassWrapper {
let yourInstance = YourClass()
var count: Int {
return yourInstance.contoursSize()
}
subscript(index: Int) -> UnsafeBufferPointer<CGPoint> {
guard 0..<count ~= index else {fatalError("Index \(index) out of bounds \(0..<count)")}
let start = yourInstance.contour(at: index)
let count = yourInstance.contourSize(at: index)
return UnsafeBufferPointer(start: start, count: count)
}
}
With these preparations above, you can access each CGPoint as:
let wrapper = YourClassWrapper()
let point = wrapper[0][1]
Or you can get the pointer to the first element in CGContour as:
let ptr = wrapper[0].baseAddress!
You may need to modify some parts to fit this into your actual code. Hope you can make it.

Cannot push past 1 element to basic AS3 Array

I am very new to this and hoping it's something that should have been obvious.
When I run the code below, the Array newHole and newArray both return 1 on the trace. Originally the code was built with only the newHole array, but I created the newArray in the hopes of troubleshooting. It did not help. The class for bulletHole contains no extra code so I didn't post that.
Thank you.
import flash.display.*;
import flash.events.*;
import flash.ui.Mouse;
Mouse.hide();
var myReticle:MovieClip;
var holeArray:Array = new Array();
var randomHole:Number = randomNumber(1, 5);
var newHole:bulletHole = new bulletHole();
var newArray:Array = new Array();
stage.addEventListener(MouseEvent.MOUSE_MOVE, followReticle);
stage.addEventListener(MouseEvent.CLICK, myFire);
stage.addEventListener(MouseEvent.CLICK, checkCount);
function followReticle(event:MouseEvent):void
{
myReticle.x = mouseX;
myReticle.y = mouseY;
}
function myFire(int):void
{
stage.addChild(newHole);
newHole.x = myReticle.x;
newHole.y = myReticle.y;
//holeArray.push(newHole);
newHole.gotoAndStop(randomHole);
//trace(holeArray.length);
}
function checkCount(int):void
{
newArray.push("A");
trace(newArray.length);
}
function randomNumber(low:Number=0, high:Number=1):Number
{
return Math.floor(Math.random() * (1+high-low)) + low;
}
Most likely the issue is that the code you've posted is running over and over again. In other words, you have a looping timeline that eventually goes back to the frame that the code you've shown is on.
Whenever that frame is reached, you have the following:
var holeArray:Array = new Array();
Which creates a new array replacing what used to be in that var.
To solve this, you either need to:
take the code out of the timeline (put it in a class file and attach that as the document class of your project)
re-architect your timeline so the first frame is only reached 1 time
put some checks in so that the code only runs the first time the frame is reached.
Here is an example of the latter option:
//just define the array, don't create it
var holeArray:Array;
//if the array is null, create it (it will only be null the first time this code is run
if(!holeArray){
holeArray = new Array();
}
This line is incorrect:
function myFire(int):void {
Because the function is triggered from a mouse event listener it should read:
function myFire(e:MouseEvent):void {
What you are doing is passing a undefined int to the function. Hope this helps.
EDIT: You should delete the clickCount event listener and function as they're not needed.
Also notice that you should move this line to the top of your myFire function or else you will keep replacing this MovieClip instead of creating it again:
var newHole:bulletHole = new bulletHole();

can't get delete function to work properly AS3

I have a Volcano class. It's purpose is to randomly spray lavaMass.
In the main class I have made it so that when my character hits the lava, everything is removed, and the deleteLava() function is called.
My problem is that with the deleteLava() function, my Volcano class stops making lava after a few 'deaths'.
Now i gets a little complicated to explain.
I found out that inside the deleteLava() function I should also remove the lavaMass from the array, for it to keep making lava no matter how many 'deaths'.
I used 'lavaSpray.shift();', and tried 'splice'..
And this worked! Except that it doesn't delete all the lavaMass, so everytime the character dies a few of the lavaMass objects keeps hanging around in the level, not moving. So after many 'deaths' there is a lot of lavaMass objects just standing still, not moving and not being deleted.
Here's the volcano class:
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Volcano extends MovieClip {
var lavaSpray:Array = [];
var lavaNum:Number;
var world:World;
public function LavaThing() {
addEventListener(Event.ENTER_FRAME, makeLava)
}
public function deleteLava()
{
this.parent.removeChild(this)
for (var m = 0; m < lavaSpray.length; m++) {
if (lavaSpray[m].parent) {
lavaSpray[m].parent.removeChild(lavaSpray[m]);
}
}
}
function makeLava (e:Event)
{
lavaNum = Math.random()*70
if (lavaSpray.length<20)
{
if (lavaNum > 68.15)
{
var lavaMass = new LavaMass();
lavaSpray.push(lavaMass);
addChild(lavaMass);
lavaMass.scaleY = 0.5;
lavaMass.scaleX = 0.5;
lavaMass.x += 90;
lavaMass.y += Math.random()*30
lavaMass.y -= Math.random()*30
}
}
for each (lavaMass in lavaSpray)
{
lavaMass.x += 4;
if (lavaMass.parent && lavaMass.x > 800)
{
lavaMass.parent.removeChild(lavaMass);
lavaSpray.shift();
}
}
}
}
}
I hope someone knows what I'm talking about. Thanks in advance.
I put up a video with my problem:
https://www.youtube.com/watch?v=rYxYHB7rcgY&feature=youtu.be
I suspect the issues is:
you don't remove the ENTER_FRAME Event Listener when you delete the lava.
removing the child doesn't mean you deleted it's listener.
so you may remove all the lava , but still the ENTER_FRAME creates more !
you have to remove it your self.
so you have to add
removeEventListener(Event.ENTER_FRAME, makeLava)
as the first line at your function deleteLava()
....
or you may add
addEventListener(Event.REMOVED_FROM_STAGE, onRemoved)
and create onRemoved(e:Event){} function
then inside this function remove any listener you Added , including the ENTER_FRAME & the REMOVED_FROM_STAGE
try to read more about these subjects
Game Loop
entity system framework
Pool Object pattern
I may but links , but I prefer you Google them , and read from different resources - whatever the language they are explained with -
good luck
just for clarrifying your question.. You added the lavamass inside the volacano class? and you need to remove lavamass or volcano ? Dp you get any error during compilation? Also i encountered some thing like this when developing a shooting game, the removed bullets shows up after removing the bullerts. What i did was , i just added the bullets into a empty movieclip and removed the entire clip.

Clearing my array leaves blank array positions

So I'm facing a problem with an AS3 class that's not operating the way I need it to. It's a simple problem, but a complex set of methods that cause it.
Firstly, the 'quiz' I'm building has 6 questions loaded as external SWFs inside of a Shell, run by a class. First we declared a var "a_quiz" to hold 6 values pushed from the external SWFs. These 6 values are reduced to a string and then checked against another array that contains the correct answers. The following loadQuiz function is designed to launch one of three random quizes and clear the a_quiz array so it can take new answers:
public function loadQuiz():void {
a_quiz.length=0;
trace("loadQuiz");
n_quizCorrect = n_quizScore = 0;
n_currentQuiz = Math.floor(Math.random() * (n_totalTopics - n_quizStart + 1) + n_quizStart);
loadTopic(n_currentQuiz);
}
Now I've tested the Shell and confirmed that the trace "loadQuiz" fires every time. And the first time you load the quiz, everything behaves as it should. The 6 questions trace correct or incorrect responses and push 6 binary values into the a_quiz array. The output looks like this:
loadQuiz
incorrect
correct
incorrect
incorrect
incorrect
incorrect
0,1,0,0,0,0
you failed
Then I jump back to the main menu and launch again. This deploys the loadQuiz function all over again. The first line of the function:
a_quiz.length=0;
should be emptying the a_quiz array to accept new answers to mark against. But when I complete the quiz I get this:
loadQuiz
correct
correct
correct
correct
correct
correct
,,,,,,1,1,1,1,1,1
you failed
For some reason beyond my understanding, the push values are stacking on top of empty positions, so when the strings compare...they won't match. What is going on here?
The push function:
function handleClick(evt:MouseEvent):void{
var tempCORRECT = a_answerSheet.toString();
var tempSELECTION = a_selected.toString();
//
if(tempSELECTION == tempCORRECT){
trace('correct');
parentObj1.a_quiz[ parentObj1.n_currentQuestion - 1 ] = 1;
}else{
trace('incorrect');
parentObj1.a_quiz[ parentObj1.n_currentQuestion - 1 ] = 0;
}
parentObj1.n_currentQuestion ++;
// GOTO NEXT SLIDE
parentObj1.LOADNEXT('up');
}
The problem originated in the loading of the Quiz itself.
as you can see on the handleClick function:
parentObj.n_currentQuestion++
was increasing an integer variable on the parentObj's timeline called n_currentQuestion. The problem then, originated in how the quiz was logging n_currentQuestion when the quiz loads with this function:
public function loadQuiz():void {
a_quiz= [];
trace("loadQuiz");
n_quizCorrect = n_quizScore = 0;
n_currentQuiz = Math.floor(Math.random() * (n_totalTopics - n_quizStart + 1) + n_quizStart);
loadTopic(n_currentQuiz);
}
So to correct the error, I needed to add a line to the loadQuiz, so that it would always load with n_currentQuestion set to 1.
public function loadQuiz():void {
a_quiz= [];
n_currentQuestion = 1;
trace("loadQuiz");
n_quizCorrect = n_quizScore = 0;
n_currentQuiz = Math.floor(Math.random() * (n_totalTopics - n_quizStart + 1) + n_quizStart);
loadTopic(n_currentQuiz);
}

Flash Resetting array values

I was working on a test project that I will later incorporate into a much larger work that is a simple quiz game. I made an array with my questions:
var questions1:Array=["nitrogen dioxide","sulfur hexafluoride",..."]
and in a second layer I made a button that cycles through the questions randomly.
import flash.events.MouseEvent;
var qno=0;var rnd1;
function change_question(){
rnd1=Math.ceil(Math.random()*questions1.length)-1;
q.text=questions1[rnd1];
if(questions1[rnd1]=="X"){change_question();}
questions1[rnd1]="X";
}
change_question();
next_b.addEventListener(MouseEvent.CLICK, ButtonAction1);
function ButtonAction1(eventObject:MouseEvent){
qno++;change_question();
}
This part works great, because I was following a tutorial. Text appears in a dynamic text box I created as it should. This tutorial taught to change the value of the array to X with every choice and to ignore choose a different question every time it encountered an X
After it cycles through all the questions I basically get an infinite loop in my output section of flash because it can't find any more non-X values. I was hoping someone had information on how to press a button an change the array back to its default settings so that a teacher (because that is who it is for) has a way of resetting the file when they have reached the end of the quiz.
Thanks everyone!
As per my understanding you wanted to randomize your questions and after showing all the entire questions you wanted to reset your questions.
As per your code you get a random question and updating the same array by pushing value 'X'. Rather than doing this what you need to do is to preserve the array only randomize its position. So that you can use the same value once you cover your all questions
I have added code here.
import flash.events.MouseEvent;
var qno=0;var rnd1;
var questions1:Array=["nitrogen dioxide","sulfur hexafluoride","carbon dioxide","carbon monooxide"];
var nAttmeptedCount = 0;
var shuffledLetters:Array;
function change_question()
{
if(qno == questions1.length)
{
qno = 0;
resetQuestion()
}
else
{
q.text = questions1[shuffledLetters[qno]];
qno++;
}
}
function resetQuestion()
{
shuffledLetters = new Array(questions1.length);
for(var i=0;i<shuffledLetters.length;i++)
{
shuffledLetters[i] = i;
}
shuffledLetters.sort(randomize);
}
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
resetQuestion()
change_question();
next_b.addEventListener(MouseEvent.CLICK, ButtonAction1);
function ButtonAction1(eventObject:MouseEvent){
change_question();
}
In above solution after showing all questions I have reset the questions automatically. you can modify code as per your requirement. If you want to do the reset questions you can put you code qno = 0;resetQuestion() on button click.
hope above solution work for you.

Resources