Ideally, I would like them all running, but when I have the second and/or third one active, Script 1 fails. (It just does nothing)
I wonder, is it possible to merge them into one script? Would that solve the problem? (I am tempted to try cutting and pasting them into one script just to see what happens)
Script 1 (the reloader)
(function () {
"use strict";
function walkTheDOM(node, func) {
if (node && node.nodeType) {
if (typeof func === "function") {
func(node);
}
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
}
function filterElementsByContains(elements, string) {
var toStringFN = {}.toString,
text = toStringFN.call(elements),
result,
length,
i,
element;
if (text !== "[object NodeList]" && text !== "[object Array]" && !($() instanceof jQuery)) {
return result;
}
result = [];
if (typeof string === "string") {
string = new RegExp("^" + string + "$");
} else if (toStringFN.call(string) !== "[object RegExp]") {
return result;
}
function getText(node) {
if (node.nodeType === 3) {
text += node.nodeValue;
}
}
length = elements.length;
i = 0;
while (i < length) {
text = "";
element = elements[i];
walkTheDOM(element, getText);
if (string.test(text)) {
result.push(element);
}
i += 1;
}
return result;
}
if(!filterElementsByContains([document.getElementsByTagName("table")[0]], /We are proud to announce that the November discounts have been chosen/).length) {
location.reload();
}
}());
Script 2 (Jump to last sheet, if it's multi sheet)
function getPreviousLink(){
var nextLink = document.getElementById('pagination-next-link');
var links = document.getElementsByClassName('v_page_nav')[0].getElementsByTagName("a");
for(var i=0; i < links.length; i++){
if(links[i] == nextLink) { return links[i-1]; }
}
}
var link = getPreviousLink();
link.target="_blank";
link.click();
Script 3 (open previous sheet, if there is one)
var link = document.getElementById('pagination-prev-link');
link.target="_blank";
link.click();
If the second 2 scripts aren't changing anything that would cause your first script to break (like something the first script looks for gets removed by script 2).... I would suggest going into 'manage scripts' and changing the order they run in... sometimes that can fix issues like this.
Related
I'm trying to get automated tests back up and running and having the following issue when I run a test.
The objective of the function is if the selector comes from a section of a page object selector will be an array of objects starting from the outermost ancestor (section), and ending with the element Join their selectors in order.
Error message:
Error while running "getElements" command: ancestors.shift is not a function
Function:
function getSelector(selector) {
let ancestors = selector;
if (typeof ancestors !== "string") {
selector = "";
let oElement = ancestors.shift();
while (oElement) {
selector += " " + oElement.selector;
oElement = ancestors.shift();
}
}
return selector;
}
The code which calls the getSelector function below:
selector(selector) {
return featureHelper.getSelector(selector);
}
getElement(result) {
if (result.status === 0 && Array.isArray(result.value)) {
for (let i = 0; i < result.value.length; i++) {
if (typeof result.value[i] === "object") {
result.value[i].ELEMENT =
result.value[i][Object.keys(result.value[i])[0]];
}
}
return result;
} else {
return result;
}
}
};
I'm trying to write a simple function that iterates through text and replaces any href's it comes across with text instead;
var REPLACE = [
{expression: www.anyhref.com, value: 'website'}
];
function(instance) {
instance = function {
var insteadURL;
insteadURL: = REPLACE.match(function(expression) {
return element.classList.contains(expression);
});
return(
insteadURL ? insteadURL.value : getElementText(expression)
);
}
}
I feel as though I may not be using the match method or the conditional operator properly but from what I understand this should work. But of course it doesn't.
If you're trying to replace links (i guess) in your text, try this regex:
/<a.*?href="www.anyhref.com".*?\/a>/g
Then you would have to add for each href you want to replace an entry in your array.
If you are in DOM context you can do the following:
To iterate through the DOM you can use this function:
function domReplace(node, iterator) {
switch (node && node.nodeType) {
case 1: case 9: case 11: {
const newNode = iterator((node.nodeName || '').toLowerCase(), node);
if (newNode && newNode != node && node.parentNode) {
node.parentNode.insertBefore(newNode, node);
node.parentNode.removeChild(node);
}
for (let child = newNode.firstChild; child; child = child.nextSibling)
domReplace(child, iterator);
} break ;
case 3: {
const newNode = iterator('#text', node);
if (newNode && newNode != node && node.parentNode) {
node.parentNode.insertBefore(newNode, node);
node.parentNode.removeChild(node);
}
} break ;
}
}
Then you can replace a if pattern matches .href with custom text:
domReplace(document, (type, node) => {
if (type == 'a') {
for (let i = 0; i < REPLACE.length; i += 1)
if (~(node.href || '').indexOf(REPLACE[i].expression))
return document.createTextNode(REPLACE[i].value);
return document.createTextNode(node.href);
}
return node;
});
Note you should not give document to domReplace but the right dom node to avoid full page replacement
If the text We are sorry but we made a boo boo appears then
Wait 5 seconds
reload
I would like to do this in JavaScript.
Here is an attempt
(function () {
"use strict";
function walkTheDOM(node, func) {
if (node && node.nodeType) {
if (typeof func === "function") {
func(node);
}
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
}
function filterElementsByContains(elements, string) {
var toStringFN = {}.toString,
text = toStringFN.call(elements),
result,
length,
i,
element;
if (text !== "[object NodeList]" && text !== "[object Array]" && !($() instanceof jQuery)) {
return result;
}
result = [];
if (typeof string === "string") {
string = new RegExp("^" + string + "$");
} else if (toStringFN.call(string) !== "[object RegExp]") {
return result;
}
function getText(node) {
if (node.nodeType === 3) {
text += node.nodeValue;
}
}
length = elements.length;
i = 0;
while (i < length) {
text = "";
element = elements[i];
walkTheDOM(element, getText);
if (string.test(text)) {
result.push(element);
}
i += 1;
}
return result;
}
if(filterElementsByContains([document.getElementsByTagName("table")[0]], /We are sorry but we made a boo boo/).length) {
location.reload();
}
The above could should, I think, work for the text if it appears in a specific place. I want to make it more general - so that the text could appear anywhere on that page.
Also, I would like to know how to add a pause so that, for example, it waits 5 seconds before reloading.
I guess I would add incorporate something like:
setTimeout(
function()
{
//location.reload();
}, 5000);
Just do an indexOf on the body's textContent/innerText property
var content = document.body.textContent || document.body.innerText;
var hasText = content.indexOf("We are sorry but we made a boo boo")!==-1;
if(hasText){
setTimeout(function(){
window.location = "http://www.example.com";
},5000);
}
This may work:
var bodyText = document.body.textContent || document.body.innerText;
var msg = "We are sorry but we made a boo boo";
if (bodyText.indexOf(msg) > -1) {
setTimeout(function() {
location.reload();
}, 5000);
}
--sorry for nearly duplicate answer :\ --
--edit--
Tell me - how can I add a second rule, it's a different way of
phrasing the error message: There was an internal error in our system.
We logged the problem and will investigate it later.
This will check for both messages:
var bodyText = document.body.textContent || document.body.innerText;
var msg = [
"We are sorry but we made a boo boo",
"There was an internal error in our system. We logged the problem and will investigate it later."
];
var flag = false;
for (var i = 0; i < msg.length; i++) {
if bodyText.indexOf(msg[i]) {
flag = true;
}
}
if (flag) {
setTimeout(function() {
location.reload();
}, 5000);
}
Explanation: All I did was modify msg to be an array of strings rather than a string itself. Then for every msg we want to check, we loop through the values and compare msg against bodyText. If bodyText contains one of the msg's, we set a flag to true, and then perform an if statement on flag.
If you want to check anywhere in the page... then you have to do just that. Get every DOM element and check if there is your String there... I do not think there is another way.
Yes using setTimeout will do the trick for waiting before reload.
I am trying to solve a similar problem and running into issues.
Javascript recursion completes before traversing the whole tree?.
I have the same function listFiles but with two parameters. The second parameter is the folder name that is passed to this function. The function should return the filenames that fall under the passed foldername. For eg. if the folder name passed is 'js' then the function should return 5 files i.e - main.js', 'app.js', 'misc.js', 'jquery.js' and 'underscore.js'. Here is the code i am trying to write to achieve the result -
function listSubfolder(fileSystem, subFolder){
var result = [];
for(var i=0; i<fileSystem.files.length; i++){
if(typeof fileSystem.files[i] !== 'string') {
fileSystem = fileSystem.files[i];
findFiles(fileSystem);
}
}
function findFiles(fileSystem) {
var files = fileSystem.files;
if (typeof files !== 'undefined') {
for (var i = 0; i < files.length; i++) {
if (typeof files[i] === 'string') {
result.push(files[i]);
} else {
findFiles(files[i]);
}
}
}
}
return result;
}
There are a couple problems here. The first is scope.
You're passing a parameter fileSystem into the function (L1):
function listSubfolder(fileSystem, subFolder){
but you're redefining it within the function (L5):
fileSystem = fileSystem.files[i];
The same thing is happening on your findFiles function (L10) as well. You're specifying fileSystem again (which doesn't happen to break the original fileSystem object from listSubFolder but it may cause errors in the future) so I would rename that parameter as well.
The second problem now is you need to check if the files are from the specified sub folder (L4):
if(typeof fileSystem.files[i] !== 'string' && fileSystem.files[i].dir === subFolder) {
The final edit should look something like this:
function listSubfolder(fileSystem, subFolder){
var result = [],
fArr;
for(var i=0; i<fileSystem.files.length; i++){
if(typeof fileSystem.files[i] !== 'string' && fileSystem.files[i].dir === subFolder) {
fArr = fileSystem.files[i];
findFiles(fArr);
}
}
function findFiles(f) {
var files = f.files;
if (typeof files !== 'undefined') {
for (var i = 0; i < files.length; i++) {
if (typeof files[i] === 'string') {
result.push(files[i]);
} else {
findFiles(files[i]);
}
}
}
}
return result;
}
The main problem with the code you provided is that you are not checking the current folder to see if you are within subFolder. You can add an extra Boolean parameter to the findFiles method that tracks if you are in the specified subfolder or not. Only if that is true should you add the files to result.
There's also a bug in your first loop where you were changing fileSystem each time through the loop. You can just remove that loop though and have findFiles process the root folder like all the others.
function listSubfolder(fileSystem, subFolder){
var result = [];
function findFiles(fileSystem, inSubFolder) {
var files = fileSystem.files;
if (typeof files !== 'undefined') {
for (var i = 0; i < files.length; i++) {
if (typeof files[i] === 'string') {
if (inSubFolder) {
result.push(files[i]);
}
} else {
var currentInSubFolder = (files[i].dir === subFolder);
findFiles(files[i], inSubFolder || currentInSubFolder);
}
}
}
}
findFiles(fileSystem, false);
return result;
}
I have a bit of javascript code to find and replace text into an image. I then gather the font size of the original text and use that to set the size of the new image.
Problem is, I keep getting the error: Could not convert JavaScript argument arg 0 [nsIDOMWindow.getComputedStyle]
Code:
function findAndReplace(searchText, replacement, searchNode) {
if (!searchText || typeof replacement === 'undefined') {
// Throw error here if you want...
return;
}
var regex = typeof searchText === 'string' ?
new RegExp(searchText, 'g') : searchText,
childNodes = (searchNode || $("body").get(0)).childNodes,
excludes = 'html,head,style,title,link,meta,script,object,iframe';
var cnLength = childNodes.length;
while (cnLength--) {
var currentNode = childNodes[cnLength];
if (currentNode.nodeType === 1 &&
(excludes + ',').indexOf(currentNode.nodeName.toLowerCase() + ',') === -1) {
arguments.callee(searchText, replacement, currentNode);
}
if (currentNode.nodeType !== 3 || !regex.test(currentNode.data) ) {
continue;
}
var parent = currentNode.parentNode;
var frag = (function(){
var html = currentNode.data.replace(regex, replacement);
var wrap = document.createElement('div');
var frag = document.createDocumentFragment();
wrap.innerHTML = html;
while (wrap.firstChild) {
frag.appendChild(wrap.firstChild);
}
console.log(currentNode);
var jQNode = $(currentNode);
console.log("yay");
// var fontSize = jQNode.css('font-size');
if (!currentNode || currentNode == document) currentNode = document.body
var fontSize = getStyle(currentNode, 'font-size');
console.log("tast");
var heightPixels = fontSizeToPixels(fontSize);
$(".InLogo",frag).each(function(){
$(this).css("height", heightPixels+"px");
});
return frag;
})();
parent.insertBefore(frag, currentNode);
parent.removeChild(currentNode);
}
}
function getStyle(el,styleProp) {
var camelize = function (str) {
return str.replace(/\-(\w)/g, function(str, letter){
return letter.toUpperCase();
});
};
if (el.currentStyle) {
return el.currentStyle[camelize(styleProp)];
} else if (document.defaultView && document.defaultView.getComputedStyle) {
return document.defaultView.getComputedStyle(el,null)
.getPropertyValue(styleProp);
} else {
return el.style[camelize(styleProp)];
}
}
The error occurs at this line return document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp); of getStyle()
something.childNodes includes textNodes as well as Elements, and that's a problem for the getStyle() function.
Nodes don't have a style (Elements do), so who knows what will happen when you feed getStyle something that has .data; a plain Node.
Check for the existence of style to avoid the run-time error:
FIX:
var fontSize = currentNode.style ? getStyle(currentNode, 'font-size') : 0;