FF Extension - Not Keeping Global Variable Values - javascript

I'm working on a FF extension that in short, loads dynamic images into a sidebar. The ID's that I get are from a JSON response, and are stored in a global variable declared in the same .js file as I intend to use it. My problem is when I try to simulate paging through my results. I load the sidebar using my global variable and everything is ok. When I try to then move on to the next set of images to display using the ID's i've stored in my global variable it failes due to my variable having been completely reset. I'll see if I can give a rough view of my code:
var searchVars = {
'keyword': "",
'totalResults': 0,
'imgIds': [],
'cIds': [],
'curPg': "1",
'dispStartIdx': 0,
'dispEndIdx': 4,
'dispPerPg': 5,
toString: function() {
return this.keyword + ", " +
this.totalResults + ", " +
this.imgIds + ", " +
this.cIds + ", " +
this.curPg + ", " +
this.dispStartIdx + ", " +
this.dispEndIdx + ", " +
this.dispPerPg;
}
};
var corbisquicksearch = {
onSearch: function () {
cqsearch.resetSearch(); //Resets my global variable every search
searchVars.keyword = cqsearch.getSelectedText(); //searchVars is my global variable im having trouble with
cqsearch.extendImageCache();
}
extendImageCache: function() {
var postToURL = 'http://www.agenericurl.com/Search?';
var keyword = searchVars.keyword;
var p = 1; //Page Offset for ID's returned
var size = 200; //Number of ID's returned in the response set
var query = "searchQuery=" + encodeURIComponent("q=" + keyword + "&p= " + p +"&s=" + size);
var request = new XMLHttpRequest();
request.open('post', postToURL + query, true);
request.onreadystatechange = function (aEvt) {
if (request.readyState == 4) {
alert(1);
if(request.status == 200) {
alert(2);
var responseInJSON = JSON.parse(request.responseText);
searchVars.totalResults = responseInJSON.ResultsCount;
var i = searchVars.imgIds.length;
var lastResult = i + responseInJSON.SearchResultImages.length;
while (i < lastResult) {
searchVars.imgIds[i] = responseInJSON.SearchResultImages[i].ImageId;
searchVars.cIds[i] = responseInJSON.SearchResultImages[i].CorbisId;
i++;
}
cqsearch.loadSidebar();
}
else {
dump("Error loading page\n");
}
}
};
request.send();
},
loadSidebar: function() {
//Initializing Env Variables
var sidebar = document.getElementById("sidebar");
var sidebarDoc = sidebar.contentDocument || document;
var searchInfoBox = sidebarDoc.getElementById("search_info");
var resultsBox = sidebarDoc.getElementById("img_results");
var pagingInfoBox = sidebarDoc.getElementById("paging_info");
//Loading up the search information
var searchInfo = "Displaying Results for <b>{0}<b/><br>Showing <b>{1} - {2}</b> of <b>{3}</b>";
var args = [searchVars.keyword, searchVars.dispStartIdx, searchVars.dispEndIdx, searchVars.totalResults];
var infoLbl = document.createElement("label");
infoLbl.setAttribute("value", cqsearch.strFormat(searchInfo, args));
searchInfoBox.appendChild(infoLbl);
while (resultsBox.firstChild) {
resultsBox.removeChild(resultsBox.firstChild);
}
//Loading up the image results
var i = searchVars.dispPerPg * (searchVars.curPg - 1);
var lastDisplayed = (searchVars.curPg * searchVars.dispPerPg) - 1;
alert("length" + searchVars.toString());
while (i <= lastDisplayed) {
var imageID = searchVars.imgIds[i];
var cID = searchVars.cIds[i];
var imgSrc = cqsearch.createMediaUrlParams(imageID, 'thumb', cID, false).url; //thumb, 170, hover
var img = document.createElement("image");
img.setAttribute("src", imgSrc);
alert(imgSrc);
img.setAttribute("class", "img");
var idDelimiter = "_image";
var id = cID + idDelimiter;
img.id = id;
img.addEventListener("click", function () {
cqsearch.openEnlargementPage(this.id.substring(0, this.id.indexOf(idDelimiter)));
}, false);
var imgBox = document.createElement("box");
imgBox.setAttribute("class", "imgContainer");
imgBox.appendChild(img);
resultsBox.appendChild(imgBox);
i++;
}
//Loading up paging info and functionality
var prevBtn = document.createElement("button");
prevBtn.setAttribute("label", "Previous");
prevBtn.setAttribute("oncommand", "cqsearch.prevPage()");
var nextBtn = document.createElement("button");
nextBtn.setAttribute("label", "Next");
nextBtn.setAttribute("oncommand", "cqsearch.nextPage()");
pagingInfoBox.appendChild(prevBtn);
pagingInfoBox.appendChild(nextBtn);
},
nextPage: function() {
searchVars.curPg++;
alert(searchVars.imgIds);
cqsearch.loadSidebar();
},
};
I realize its a lot of code, and I didn't post every function I have, and no, this specific URL does not work. Everything not included works fine, and does exactly what its supposed too, and nothing more which is why I left it out. But if anyone could shed some light on why my global variable is being cleared between my initial load of the sidebar, and when I click to go to the next page, I would greatly appreciate it.
If you need me to add something or clarify something please let me know and I will do so! I will probably end up sliming this code down and removing irrelevant parts.
Thanks!

If you simply want a place to store some global variables for a session, then a JavaScript Module would probably work.

Would you be able to use the client side storage to store the global variable? you will then, not lose it on page loads or refresh. You could either use this to debug and see if you are getting a page refresh because sometimes extensions are fickle and you don't even notice the refresh, but if you store the variable as a key value pair in web storage you might get past this.
localStorage.setItem('imgId', '5');
to set your key/value pair
localStorage.getItem('imgId');
to retrieve your key/value pair
Then you can set a new local storage for each series of pictures that has been displayed to the client based on the last number that is set in local storage.

Related

Display logs from the database in a textbox via html and javascript

I have a table in the Database which stores the history of queries to my website.
I want to display them on the page, and update in real-time via javascript.
I've already implemented It, but the website becames very laggy.
Here is how It looks:
I have an Api on my website to get All the logs after a specific time.
I call It in javascript every 5 seconds passing the time of page loading, and updating the content of the textbox. So we see all the logs since we entered the page, and they are updating every 5 seconds.
The problem is, that the website becames very laggy in ~5 minutes, and the textbox stops updating. Also I get an alert from my browser saying something like "This page is slowing down your browser".
my logs.js:
let server_ip = location.host
var start_of_the_page = sessionStorage.getItem('start_of_the_page');
if (!start_of_the_page) { // if no such value exists
start_of_the_page = getCurrentHawkeyeTime();
// start_of_the_page = utcToTimestamp(new Date(Date.UTC(2022, 3, 1, 0, 0, 0, 0)));
}
// save data to sessionStorage
sessionStorage.setItem('start_of_the_page', start_of_the_page);
// adding jetson logs to readonly textarea
let floatingTextArea = document.getElementById("floatingTextArea");
let xhr4logs = new XMLHttpRequest();
let url_str = 'http://' + server_ip + '/get_web_logs?time=' + start_of_the_page;
xhr4logs.open("POST", url_str, true);
console.log("created xhr with such url: " + url_str);
xhr4logs.send();
// adding event that is triggered when the response is fully received
xhr4logs.onload = function() {
console.log(xhr4logs.status + " " + xhr4logs.response);
let obj = JSON.parse(xhr4logs.response);
// let groups = obj.info.split("\n").filter((a) => a); // getting non-empty lines
floatingTextArea.value = obj.info;
floatingTextArea.scrollTop = floatingTextArea.scrollHeight;
}
setInterval(function() {
return function() {
console.log("doing new cycle...");
let url_str = 'http://' + server_ip + '/get_web_logs?time=' + start_of_the_page;
xhr4logs.open("POST", url_str, true);
console.log("created xhr with such url: " + url_str);
xhr4logs.send();
};
}(), 5000);
Would be happy to hear any comments on what could slow down the browser and if there is any other approach to display the data from the database updating it regularly.

Is there a JavaScript InDesign function to get ID value

I used the command to export the hard drive ID to drive C:
var command="wmic diskdrive get SerialNumber > C:/idhdd.txt";
app.system("cmd.exe /c\""+command+"" );
I get the text file
SerialNumber
2012062914345300
Is there a JavaScript statement to remove SerialNumber, I just want to get the ID in the text file and save it to the hard drive C.
Here's ready-to-use getDriveIDs() function that should work in any Adobe app and will return array of HDD ID strings for you. I hope this can be easily generalized for other scenarios with Windows scripting inside Adobe scripting ;-)
//----------------------------------------------------------------------//
// Detects IDs (serial numbers) of connected drives and returns them as array of strings.
var getDriveIDs = function() {
var idFile = File(Folder.temp + '/saved_hdd_serials.txt');
var scriptFile = File(Folder.temp + '/dump_hdd_serials.bat');
var scriptContent = 'wmic diskdrive get SerialNumber > ' + idFile.fsName + '\n';
var ids = []
withTempFile(scriptFile, scriptContent, function() {
scriptFile.execute();
$.writeln(idFile.length == 0); // wait for asynchronous script execution to finish
$.sleep(1);
withTempFile(idFile, undefined, function(file, lines) {
ids = lines.slice(1);
});
});
return ids;
};
//----------------------------------------------------------------------//
// utilities
var withTempFile = function(file, content, callback) {
if (undefined == content) { // read temp file
file.open('r');
content = [];
while (!file.eof)
content.push(file.readln());
} else { // write temp file
file.open('w');
file.write(content);
content = undefined;
}
file.close();
callback(file, content);
file.remove();
}
//----------------------------------------------------------------------//
// main: demo
var ids = getDriveIDs();
alert('Drive IDs:\n\t' + ids.join('\n\t'));

Twitch api freecodecamp loop issue

I am trying to complete the twitch api at freecodecamp.
I have an allTotalUsers array with the users I am looping through.
My loop appears to grabbing the info I need for each user in my allTotalUsers list correctly.
I tested this by displaying data from the offline users and it showed(multiple).
The issue is on my if(streamInfo==null) statement, the streamerName is showing duplicates only.
For example, If there is 2 offline users, Bob and John.
It will show
Bob
Bob
function showOfflineUsers() {
var onlinePeople = $('#displayInfo');
onlinePeople.html('');
//allTotalUsers is an array list that is loaded when the page loads and stored globally.
for (var i = 0; i < allTotalUsers.length; i++) {
var streamerName = allTotalUsers[i];
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status == 200) {
var json = JSON.parse(this.responseText);
// gets the status of stream(null etc)
var streamInfo = json['stream'];
if (streamInfo == null) {
onlinePeople.append("<li>" + "<a href = 'https://www.twitch.tv/" + streamerName + "'>" + streamerName + "</a>" + "</li>" + "<br>");
}
}
}
xmlhttp.open("GET", "https://api.twitch.tv/kraken/streams/" + streamerName + "?client_id=" + clientId, true);
xmlhttp.send();
};
}
As per spec
let and const declarations define variables that are scoped to the
running execution context’s LexicalEnvironment. The variables are
created when their containing Lexical Environment is instantiated but
may not be accessed in any way until the variable’s LexicalBinding is
evaluated.
So, as opposed to var which is scoped to VariableEnvironment (of execution's context), let is scoped to LexicalEnvironment.
Replace
var streamerName = allTotalUsers[i];
with
let streamerName = allTotalUsers[i];

Check if user exists in Active Directory from client side JavaScript

I am creating a ASP.NET page for creating AD user objects. I am using JQuery for client side validation (to check if user name already exists).
I found some script on Google which returns user properties if user is found in active directory (I will convert this to return bool).
However, if you run this script (below) outside of Visual Studio by directly double clicking ScriptFile.js it works perfectly but when you try the same through visual studio it gives object undefined error at var objRootDSE = GetObject('LDAP://RootDSE');
Here is the JavaScript function code:
function Search(search) {
var arrSearchResult = [];
var objRootDSE = GetObject('LDAP://RootDSE');
var strDomain = objRootDSE.Get("DefaultNamingContext");
strAttrib = "samaccountname";
objConnection = new ActiveXObject("ADODB.Connection");
objConnection.Provider = "ADsDSOObject";
objConnection.Open("ADs Provider");
objCommand = new ActiveXObject("ADODB.Command");
objCommand.ActiveConnection = objConnection;
var Dom = "LDAP://" + strDomain;
var arrAttrib = strAttrib.split(",");
objCommand.CommandText = "Select '" + strAttrib + "' From '" + Dom + "' WHERE objectCategory = 'user' AND objectClass='user' AND samaccountname='" + search + "' ORDER BY samaccountname ASC";
try {
objRecordSet = objCommand.Execute();
objRecordSet.Movefirst;
while (!(objRecordSet.EoF)) {
var locarray = new Array();
for (var y = 0; y < arrAttrib.length; y++) {
locarray.push(objRecordSet.Fields(y).value);
}
arrSearchResult.push(locarray); objRecordSet.MoveNext;
}
return arrSearchResult;
}
catch (e)
{ alert(e.message); }
}
Please suggest how to make this work in visual studio or some other way to check if user exists in AD from client side.

Get String Value of Blob Passed to e.parameter in Apps Script

I'm using this code to get a blob passed to a function:
function submit(e){
var arrayBlob = e.parameter.arrayBlob;
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
This is the error I get:
Execution failed: TypeError: Can not find getDataAsString function in
the Blob object.'arrayBlob'
How do I get the string value of this blob?
Here is my code:
function showList(folderID) {
var folder = DocsList.getFolderById(folderID);
var files = folder.getFiles();
var arrayList = [];
for (var file in files) {
file = files[file];
var thesesName = file.getName();
var thesesId = file.getId();
var thesesDoc = DocumentApp.openById(thesesId);
for (var child = 0; child < thesesDoc.getNumChildren(); child++){
var thesesFirstParagraph = thesesDoc.getChild(child);
var thesesType = thesesFirstParagraph.getText();
if (thesesType != ''){
var newArray = [thesesName, thesesType, thesesId];
arrayList.push(newArray);
break;
}
}
}
arrayList.sort();
var result = userProperties.getProperty('savedArray');
arrayList = JSON.stringify(arrayList);
var arrayBlob = Utilities.newBlob(arrayList);
Logger.log("arrayBlob #1 = " + arrayBlob.getDataAsString()); // Here it`s OK
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setWidth(550).setHeight(450);
var panel = app.createVerticalPanel()
.setId('panel');
panel.add(app.createHidden('arrayBlob', arrayBlob));
var label = app.createLabel("Selecione os itens desejados").setStyleAttribute("fontSize", 18);
app.add(label);
arrayList = JSON.parse(arrayList);
panel.add(app.createHidden('checkbox_total', arrayList.length));
for(var i = 0; i < arrayList.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(arrayList[i][0]);
Logger.log("arrayList[i][0] = " + arrayList[i][0]);
Logger.log("arrayList[i] ====> " + arrayList[i]);
panel.add(checkbox);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
var scroll = app.createScrollPanel().setPixelSize(500, 400);
scroll.add(panel);
app.add(scroll);
mydoc.show(app);
}
function submit(e){
var arrayBlob = e.parameter.arrayBlob;
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
// Continues...
}
I'd like the solution worked with more than one user simultaneous using the script.
Update:
Add a global variable OUTSIDE of any function:
var arrayBlob = Utilities.newBlob("dummy data");
function showList(folderID) {
Code here ....
};
Check that the code has access to the blob:
function submit(e){
Logger.log("arrayBlob.getDataAsString(): " + arrayBlob.getDataAsString());
//More Code . . .
}
This solution eliminates the need of embedding a hidden element in the dialog box with a value of the blob.
You won't need this line:
panel.add(app.createHidden('arrayBlob', arrayBlob));
There are other changes I'd make to the code, but I simply want to show the main issue.
Old Info:
In the function showList(), the method getDataAsString() works on the blob named arrayBlob.
Logger.log("arrayBlob #1 = " + arrayBlob.getDataAsString()); // Here it`s OK
In the function, submit(), the same method does not work.
var arrayBlob = e.parameter.arrayBlob;
In the function showList(), the code is assigning a newBlob to the variable arrayBlob. So arrayBlob is available to have the getDataAsString() method used on it.
var arrayBlob = Utilities.newBlob(arrayList);
In the function, submit(), you are trying to pass the arrayBlob blob variable into the submit() function, and reference it with e.parameter.
If you put a Logger.log() statement in the submit() function.
function submit(e){
Logger.log('e: ' + e);
Logger.log('e.parameter` + e.parameter);
var arrayBlob = e.parameter.arrayBlob;
Those Logger.log statements should show something in them. If there is nothing in e.parameter, then there is nothing for the .getDataAsString() to work on.
It looks like you are putting the arrayBlob into a hidden panel.
panel.add(app.createHidden('arrayBlob', arrayBlob));
But when the object is getting passed to the submit(e) function, the arrayBlob might not be getting put into that object.
So, what I'm saying is, the:
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
Line may be perfectly good, but there is no arrayBlob there to work on. This hasn't fixed your problem, but do you think I'm understanding part of what is going on?
I'm not sure why you are using Blob's here at all, you could simply work with JSON instead.
However, if you have a reason to use Blobs, you can pass the JSON data through your form and create the Blob in your handler, as the modified code below does:
function showList(folderID) {
var folder = DocsList.getFolderById(folderID);
var files = folder.getFiles();
var arrayList = [];
for (var file in files) {
file = files[file];
var thesesName = file.getName();
var thesesId = file.getId();
var thesesDoc = DocumentApp.openById(thesesId);
for (var child = 0; child < thesesDoc.getNumChildren(); child++){
var thesesFirstParagraph = thesesDoc.getChild(child);
var thesesType = thesesFirstParagraph.getText();
if (thesesType != ''){
var newArray = [thesesName, thesesType, thesesId];
arrayList.push(newArray);
break;
}
}
}
arrayList.sort();
var result = UserProperties.getProperty('savedArray');
//get JSON data pass through form.
var arrayBlob = JSON.stringify(arrayList);
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setWidth(550).setHeight(450);
var panel = app.createVerticalPanel()
.setId('panel');
//include JSON Data in the form.
panel.add(app.createHidden('arrayBlob', arrayBlob));
var label = app.createLabel("Selecione os itens desejados").setStyleAttribute("fontSize", 18);
app.add(label);
panel.add(app.createHidden('checkbox_total', arrayList.length));
for(var i = 0; i < arrayList.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(arrayList[i][0]);
Logger.log("arrayList[i][0] = " + arrayList[i][0]);
Logger.log("arrayList[i] ====> " + arrayList[i]);
panel.add(checkbox);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
var scroll = app.createScrollPanel().setPixelSize(500, 400);
scroll.add(panel);
app.add(scroll);
mydoc.show(app);
}
function submit(e){
var arrayBlob = Utilities.newBlob(e.parameter.arrayBlob);
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
// Continues...
}
In the method you were using originally, the Blob itself was never included in the form, you were simply passing the string "Blob" around.
This is because the function createHidden(name, value); expects two strings as parameters, so it calls ".toString()" on the arrayBlob object, which returns the string "Blob".

Categories

Resources