I did do some research on google and the userscripts site but was unsuccessful in finding an answer.
So basically how can I check if specific text is found on a page?
And the text is in no special tags or anything.
A crude but fast way, for FF GM:
if (/Text you are looking for/i.test (document.body.innerHTML) )
{
alert ("Found it!");
}
//--- Looking for one of two different texts...
if (/(Text ONE that you are looking for)|(Text TWO that you are looking for)/i.test (document.body.innerHTML) )
{
alert ("Found one!");
}
For more focused searches use jQuery contains as in this previous question.
for example this script will show if the text specific text is found on this page.
// ==UserScript==
// #name so5059986
// #namespace test
// #description test
// #include http://stackoverflow.com/questions/5059986/how-to-have-greasemonkey-check-if-text-if-found-on-page
// ==/UserScript==
var xpathResult = document.evaluate("(//text()[contains(., 'specific text')])[1]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
var node=xpathResult.singleNodeValue;
if (node==null)
alert("text not found");
else
alert("text found on page");
I don't know what you mean with special tags. Text is always inside some tags.
Related
My extension has a context menu with items. What I'd like it to do: is when I right-click an editable html element (eg input or textarea) and then select and click on an item in my menu - some value defined by my extension gets entered into the input.
For now I have realised that with document.activeElement.value = myValue.
With simple inputs it works alright.
Problems start when there is an input with custom onChange event handling, eg a calendar or a phone input, or currency input - that transforms user-input in some way.
Since I am setting a value directly onto the element - the handling logic gets omitted, which causes all manner of problems.
Since javascript doesn't allow for KeySend-like features - what are my options here?
I have thought about testing tools like Puppeteer or Cypress - but they all seem not to be packageable into an extension. Puppeteer does have such an option, but it still requires a node instance running to connect to. And I would like my extension to be solely client-sided and distributed in Chrome webstore - so I cannot ask my users to spin up a node server.
There is a built-in DOM method document.execCommand.
In case of an extension, use this code in the content script.
// some.selector may be `input` or `[contenteditable]` for richly formatted inputs
const el = document.querySelector('some.selector');
el.focus();
document.execCommand('insertText', false, 'new text');
el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed
It imitates physical user input into the currently focused DOM element so all the necessary events will be fired (like beforeinput, input) with isTrusted field set to true. On some pages the change event should be additionally dispatched as shown above.
You may want to select the current text to replace it entirely instead of appending:
replaceValue('some.selector', 'new text');
function replaceValue(selector, value) {
const el = document.querySelector(selector);
if (el) {
el.focus();
el.select();
if (!document.execCommand('insertText', false, value)) {
// Fallback for Firefox: just replace the value
el.value = 'new text';
}
el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed
}
return el;
}
Note that despite execCommand being marked as obsolete in 2020, it'll work in the foreseeable future because a new editing API specification is not finished yet, and knowing how slow such things usually move it may take another 5-20 years.
#wOxxOm, thank you very much !
I used your code solved my problem which has bothered me for long time. I googled many code and article for nearly one month.
It works on Facebook and many strong website.
Because execCommand has depredated, I try below code it works well, include Facebook.
function imitateKeyInput(el, keyChar) {
if (el) {
const keyboardEventInit = {bubbles:false, cancelable:false, composed:false, key:'', code:'', location:0};
el.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
el.value = keyChar;
el.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed
} else {
console.log("el is null");
}
}
The following code can only work on ordinary websites, but it is invalid for strong website.
function fireKeyEvent(el, evtType, keyChar) {
el.addEventListener(evtType, function(e) {el.value += e.key;}, false);
el.focus();
const keyboardEventInit = {bubbles:false, cancelable:false, composed:false, key:keyChar, code:'', location:0};
var evtObj = new KeyboardEvent(evtType, keyboardEventInit);
el.dispatchEvent(evtObj);
}
In my XPages application I am using the xe:dynamicViewPanel control and would like to add a standby/wait dialog/popup when a section is being expanded by the user (click on the expand-icon to open the section).
Sometimes the view index is not up-to-date and opening a category holding a lot of documents will last a while, in the meantime I want to display some "loading dialog" (which I already have, so, no need to explain how to do this).
My problem is, that I can not find any event or entry point where to start from.
Thank you all !
Alex
You can try code from this link:
https://openntf.org/XSnippets.nsf/snippet.xsp?id=standby-dialog-custom-control
If you want to show stanby dialog on the current section, replace the 79 line
var forms=dojo.body()
with some other container. For example, a partial refresh element
var forms = dojo.byId(refreshId)
In this case you need to replace lines 75 and 140 to pass the id parameter
function StandbyDialog_Started(refreshId) {
try{
if(StandbyDialog_Do==true){
if(this.StandbyDialog_Obj==null) {
var forms= (refreshId)?dojo.byId(refreshId):dojo.body();
this.StandbyDialog_Obj = new dojox.widget.Standby({
target: forms,
zIndex: 10000
});
document.body.appendChild(this.StandbyDialog_Obj.domNode);
this.StandbyDialog_Obj.startup();
}
StandbyDialog_StoreField()
setTimeout("if(StandbyDialog_Do==true){StandbyDialog_StoreField()}",50);
setTimeout("if(StandbyDialog_Do==true){this.StandbyDialog_Obj.show()}",200);
}
}catch(e){
console.log("StandbyDialog_Started:"+e.toString())
}
}
and
dojo.subscribe( 'partialrefresh-start', null, function( method, form, refreshId ){
StandbyDialog_Do=true
StandbyDialog_Started(refreshId)
});
I didn't test it, but I hope it can help you to go further.
I'm using a service called Embedly to style my RSS feeds from Google Feedburner. I have an example code over her: JsFiddle
If you look closely you will see the source (CNN) at the end of every title. This is called .provider I would like to get rid of the whole div (.embed) IF the the word CNN is located elsewere (meaning duplicate) in the div, either .description or a
I tried many things, this is one of them really straight forward code:
$('.embed').each(function() {
if($('.embed a:first **could also be .description**', this).text() == $('.provider', this).text())
$(this).remove();
});
I cant figure out why its not working. I also used it with on and live click with no luck.
I just realized the 'embeds' are not there on document tready. I added a button with click event which you can click after the embedly has loaded in: http://jsfiddle.net/2VBSX/37/
You can use success event to filter provider class from the data like this :
EDITED
$('div.newscontainer').embedly({
key: ':3eccf441bf0f43acbb076da9817af27d',
success: function(oembed, dict) {
output = $(oembed['code']);
description = $(oembed['code']).find(".description").text();
var regex =new RegExp(output.find('.provider').text(),"i");
if(regex.exec(description) == null ) {
$(dict["node"]).parent().html(output);
}
output.find("a:eq(0)").text(); // First
output.find("a:eq(1)").text(); // Provider
}
});
Checkout this jsfiddle demo
Is it that what you want?
var regex = /CNN/;
$('.embed').each(function(index, element) {
if (regex.exec($('.embed a:first').text()) != null
&& regex.exec($('.provider').text()) != null) {
element.remove();
}
});
I have a list with items.
When I click any of these items, I copy its id-value into a form text-field.
Everytime I click, it replaces the value, which is correct by default. But what I would like to add, is a way for the user to hold down a key on their keyboard, and when they then click, they just .append whatever they just clicked into the same form field.
Here's my jQuery-code I'm using for the first/default scenario:
$(function(){
$('ul#filter-results li').click(function(){
var from = $(this).attr('id'); // get the list ID and
$('input#search').val(from+' ').keyup(); // insert into text-field then trigger the search and
$('input#search').focus(); // make sure the field is focused so the user can start typing immediately
});
});
Is there a way to implement some sort of keyboard key-listener?
Something like:
if (e.shiftKey){
.append('this text instead')
}
haven't tried out to see if shiftKey is even any valid name here
shiftKey is of one of the properties of the event object and is valid to be used. try this:
$(document).on('keyup click', function(e){
if (e.shiftKey) {
$('input#search').focus()
$('input#search').val(e.target.id)
}
})
DEMO
$('ul#filter-results').on('click', 'li', function(e) {
if(e.shiftKey) {
do something;
} else {
do something else;
}
});
There is a jQuery plugin for extended click.
You could try that or see how they have done it and implement it yourself.
ExtendedClick plugin
Hope this helps.
This is what I ended up with:
I switched over to altKey because shiftKey marked a lot of text when I clicked.
Didn't do anything besides it doesn't look good...
$(function(){
$('ul#filter-results li').click(function(e){
var text = $(this).attr('id'); // get the ID
var input = $('#search'); // form field to insert text into
if (e.altKey){ input.val(input.val()+', '+text+' ').keyup(); } // fetch whatever is already there, and add some more
else { input.val(text+' ').keyup(); } // just replace whatever is already there
$('#search').focus();
});
});
Thanks for good suggestions...
I am writing a Google extension. Here my content script modifies a page based on a list of keywords requested from background. But the new innerHTML does not show up on the screen. I've kluged it with an alert so I can see the keywords before deciding to actually send a message, but it is not how the routine should work. Here's the code:
// MESSAGE.JS //
//alert("Message Page");
var keyWordList= new Array();
var firstMessage="Hello!";
var contentMessage=document.getElementById("message");
contentMessage.value=firstMessage;
var msgComments=document.getElementsByClassName("comment");
msgComments[1].value="Hello Worlds!";//marker to see what happens
chrome.extension.sendRequest({cmd: "sendKeyWords"}, function(response) {
keyWordList=response.keyWordsFound;
//alert(keyWordList.length+" key words.");//did we get any keywords back?
var keyWords="";
for (var i = 0; i<keyWordList.length; ++i)
{
keyWords=keyWords+" "+keyWordList[i];
}
//alert (keyWords);//let's see what we got
document.getElementsByClassName("comment")[1].firstChild.innerHTML=keyWords;
alert (document.getElementsByClassName("comment")[1].firstChild.innerHTML);// this is a band aid - keyWords does not show up in tab
});
document.onclick= function(event) {
//only one button to click in page
document.onload=self.close();
};
What do I have to do so that the text area that is modified actually appears in the tab?
(Answering my own question) This problem really has two parts. The simplest part is that I was trying to modify a text node by setting its value like this:
msgComments1.value="Hello Worlds!"; //marker to see what happens
To make it work, simply set the innerHTML to a string value like this:
msgComment1.innerHTML="Hello Worlds!"; //now it works.
The second part of the problem is that the asynchronous call to chrome.extension.sendRequest requires a callback to update the innerHTML when the reply is received. I posted a question in this regard earlier and have answered it myself after finding a solution in an previous post by #serg.