List of Persistent Favourites - javascript

I need to keep track of a list of 25 favourites which are added from a list of ~100 entries. These favourites would be in a list of say
"favourite 1"
"favourite 2"
"favourite 3"
.... so on
and I need them to be stored persistently. I also would require them to be able to be deleted and replaced with another favourite string value. I have looked at How do I store an array in localStorage? but that doesn't work for me because when I declare var names=[]; on the javascript file, every time my favourites function runs it redeclares the array and clears everything.
I have tried doing something like:
function addToFav(string)
{
if (localStorage.fav1) // if fav1 was created before
{
alert("local storage fav1 present, don't make variables");
}
else
{
alert('fav variables never made, make them now');
var i=1;
for (i=1; i<=25; i++)
{
var favNumber = "fav" + i;
localStorage.favNumber = "x";
}
alert(localStorage.fav1); // outputs "undefined"
}
}
it was my intention to make localStorage variables of fav1,fav2,fav3...fav25 and then manage them individually. But this doesn't work since calling localStorage.favNumber = "x"; makes the local storage variable favNumberequal to "x" and not fav+i.
I'm out of ideas at the moment; I have looked at http://playground.html5rocks.com/#async_transactions to try using a HTML5 database but I'm very new to web development and it seems a bit too much for what I'm trying to do. Does anyone know how to fix this issue? Any information would be helpful.

This might help. I use these to store info in Local Storage with cookie backup...
function setLocalStorage(c_name, value) {
var exdays = 30;
// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {
localStorage[c_name] = value;
} else {
var exdate = new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
document.cookie = c_name + "=" + c_value;
}
}
function getLocalStorage(c_name) {
// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {
return localStorage[c_name];
} else {
var i, x, y, ARRcookies = document.cookie.split(";");
for (i = 0; i < ARRcookies.length; i++) {
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == c_name) {
return unescape(y);
}
}
}
}

Related

How to underline charachters in InDesign with JavaScript?

I started writing this piece of code for InDesign to underline all letters except from the one with descendants, and added a dialog window to chose stroke and offset of the line.
Now I have two problems:
the program underlines all letters
the stroke and offset won't change
I'm a beginner in Javascript and it's the first time coding for InDesign. Does someone have a clue? Thank you!
// UNDERLINE ALL BUT NO DESCENDANTS
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if (app.documents.length != 0){
try {
// Run script with single undo if supported
if (parseFloat(app.version) < 6) {
main();
} else {
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Expand State Abbreviations");
}
// Global error reporting
} catch ( error ) {
alert( error + " (Line " + error.line + " in file " + error.fileName + ")");
}
}else{
alert("Open a document first before running this script.");
}
///MAIN FUNCTION
function main(){
if(app.selection.length != 0){
myDisplayDialog();
}
}
//INTERFACE
function myDisplayDialog(){
//declare variables
//general
var myDoc = app.activeDocument;
var mS = myDoc.selection;
// dialog
var myDialog = app.dialogs.add({name:"Underliner"});
var myLabelWidth = 70;
with(myDialog.dialogColumns.add()){
with(borderPanels.add()){
with(dialogColumns.add()){
with(dialogRows.add()){
staticTexts.add({staticLabel:"Stroke:", minWidth:myLabelWidth});
staticTexts.add({staticLabel:"Offset:", minWidth:myLabelWidth});
}
}
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:1, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue: 15, editUnits:MeasurementUnits.points});
}
}
}
var myResult = myDialog.show();
if(myResult == true){
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS,myStroke,myOffset);
}
else{
myDialog.destroy();
alert("Invalid page range.");
}
}
//REAL FUNCTION
function underline(charList,stroke, offset){
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'];
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
//console.log(typeof myText);
if (includes(myChar, doNotUnderline) == false)
{
myChar.underline = true;
myChar.underlineWeight == stroke;
myChar.underlineOffset == offset;
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
//function to know if char is in array
function includes(elemento,array)
{
var len = array.length;
for(var i=0; i<len ;i++)
{
if(array[i]==elemento){return true;}
}
return false;
}
Try these changes in the function underline():
//REAL FUNCTION
function underline(words,stroke, offset) { // <------ here 'words' instead of 'charList'
var charList = words[0].characters; // <------ here get 'characters' of the 'words'
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'].join(); // <------- here '.join()'
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
// if (includes(myChar, doNotUnderline) == false) // <----- no need
if (doNotUnderline.indexOf(myChar.contents) < 0) // <------ 'indexOf()' instead of 'includes()'
{
myChar.underline = true;
myChar.underlineWeight = stroke; // <------- here '=' instead of '=='
myChar.underlineOffset = offset; // <------- here '=' instead of '=='
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
Probably there can be another improvements as well. It's need additional researches. But if you change these lines it should work to a degree.
And there is one little thing that improves user experience greatly: to keep last used values in the input fields. It can be done pretty easy, let me know it you need it.
Update
Here is the way I'm using to store and restore any preferences of my scripts.
Add somewhere at the start of your script these lines:
// get preferences
var PREFS = { stroke: 1, offset: 15 }; // set default prefs
var PREFS_FILE = File(Folder.temp + '/underline_prefs.json'); // the file with preferences
if (PREFS_FILE.exists) PREFS = $.evalFile(PREFS_FILE); // get the prefs from the file
Now you can use the global values PREFS.stroke and PREFS.offset anywhere you want. In your case they go here:
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:PREFS.stroke, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue:PREFS.offset, editUnits:MeasurementUnits.points});
}
This way script will get the stroke and weight from the file underline_prefs.json that will be stored in the standard temporary folder of current user.
Final step is to save the values back into the file after the script got them from the dialog window.
I'd put this piece of code here:
if (myResult == true) {
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS, myStroke, myOffset);
// save preferences here
PREFS.stroke = myStroke;
PREFS.offset = myOffset;
PREFS_FILE.open('w');
PREFS_FILE.write(PREFS.toSource());
PREFS_FILE.close();
} else {
myDialog.destroy();
alert("Invalid page range.");
}
Voilá. Now don't need to type the values every time they differ from default ones.

Unexpected infinite loop in Javascript

I was doing a cookie practice in javascript and developed the following code:
function getCookie(kname) {
var fullkeyname = kname + "=";
var fullcookie = document.cookie;
var acookies = fullcookie.split(";");
for (var i = 0; i < acookies.length; i++) {
var cookie = acookies[i];
while (acookies[i].charAt(0) == " ") { //THE ISSUE IS HERE
cookie = cookie.substring(1);
}
if(cookie.indexOf(fullkeyname) == 0) {
return cookie.substring(fullkeyname.length, cookie.length);
}
}
return "";
}
It didnt worked and seemed to rise and infinite loop so I tracked my code with "document.write" in various parts and discovered that if I change the "while" condition it will work as follows:
function getCookie(kname) {
var fullkeyname = kname + "=";
var fullcookie = document.cookie;
var acookies = fullcookie.split(";");
for (var i = 0; i < acookies.length; i++) {
var cookie = acookies[i];
while (cookie.charAt(0) == " ") { //RIGHT HERE
cookie = cookie.substring(1);
}
if (acookies[i].indexOf(fullkeyname) == 0) {
return cookie.substring(fullkeyname.length, cookie.length);
}
}
return "";
}
Now my code works as expected, however I dont know why, since I have set the value of cookies to "cookie=acookies[i]" I dont understand why it should loop indefinetly if I dont use the "cookie" variable.
Question is: why does the code works with my "cookie" variable and not with the "acookies[i]" even though the sould have the same value at that given moment?
It causes an infinite loop because you are checking if the first character of acookies is an empty space, then if it is, you are removing the first character of cookie (NOT acookies). Therefore, if acookies does have a space as the first character, the while statement will always be true because you aren't removing that space from acookies
function getCookie(kname) {
var fullkeyname = kname + "=";
var fullcookie = document.cookie;
var acookies = fullcookie.split(";");
for (var i = 0; i < acookies.length; i++) {
while (acookies[i].charAt(0) == " ") { //THE ISSUE IS HERE
acookies[i] = acookies[i].substring(1); // FIXED THIS LINE
}
var cookie = acookies[i];
if(cookie.indexOf(fullkeyname) == 0) {
return cookie.substring(fullkeyname.length, cookie.length);
}
}
return "";
}
edited for typo, thank you FREE_AND_OPEN_SOURCE
I see a problem in while loop
while (acookies[i].charAt(0) == " ") { //THE ISSUE IS HERE
cookie = cookie.substring(1);
}
once acookies[i].charAt(0) == " " becomes true, it will keep on looping and will never get to go outside while loop to increment the value of 'i'.
and in the second version of the code you're modifying the cookie variable itself which make the while condition false which moves the control out of the loop and continue execution.

Hide all content exception made when URL parameter is used

I want to hide my website content exception made when ?token_code=12345678 is used in URL. This is the code that's not working correctly, it hides website but never shows it:
I'm calling script by www.example.com/?authtoken=12345678
So when that parameter is included in URL it should show website. But it's not displaying it. It's only hiding it.
PS. I'm using cookies to remember "token" :)
HTML:
<body data-token="12345678"> </body>
JS:
//setCookie and readCookie
function SetCookie(e, t, n) {
var r = new Date;
var i = new Date;
if (n == null || n == 0) n = 1;
i.setTime(r.getTime() + 36e5 * 24 * n);
document.cookie = e + "=" + escape(t) + ";expires=" + i.toGMTString()
}
function ReadCookie(e) {
var t = " " + document.cookie;
var n = t.indexOf(" " + e + "=");
if (n == -1) n = t.indexOf(";" + e + "=");
if (n == -1 || e == "") return "";
var r = t.indexOf(";", n + 1);
if (r == -1) r = t.length;
return unescape(t.substring(n + e.length + 2, r))
}
function DeleteCookie(name) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
//capitalzies string
function capitalize(str) {
var first = str.charAt(0).toUpperCase();
str = str.replace(/^.{1}/, first);
return str;
}
// get's the GET paramters like so --> $_GET('var1');
function getVar(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
// Checks for one of TWO access short codes
// includeOnly && excludeOnly
// If includeOnly is not NULL, then ONLY include
// categories mentioned in that varaible.
// Also, cookie the data, that it's saved.
// Of course, if anyone re-visits the site, and
// re-writes the GET paramter, it'd delete all
// previous data in the cookie.
var token_code = ["authtoken", "excludeOnly"];
var asc = ""; //this is used to select the CURRENT access short code
var tokenValues = [];
//first check if there are ANY get params.
if (getVar(token_code[0]) != false) {
//before writing the inlcude only, delete EXCLUDE only
DeleteCookie(token_code[1]);
SetCookie(token_code[0], getVar(token_code[0]));
}
if (getVar(token_code[1]) != false) {
//before writing the EXCLUDE only, delete include only
DeleteCookie(token_code[0]);
SetCookie(token_code[1], getVar(token_code[1]));
}
//Try and reaad the cookie (there should be a cookie named "includeOnly" or "excludeOnly -- both from token_code)
//includeOnly is present?
if (ReadCookie(token_code[0]).toString().length > 0) {
//defines what the user wants to do. Exlcude or include? when token_code[0] it's include!
asc = token_code[0];
var tokens = ReadCookie(asc).toString();
tokenValues = decodeURIComponent(tokens).split(',');
//loop through each category.
//hide every category and it's children
$("[data-token]").hide();
$.each(tokenValues, function (index, value) {
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").show();
});
}
//excludeOnly is present?
if (ReadCookie(token_code[1]).toString().length > 0) {
//defines what the user wants to do. Exlcude or include? when token_code[0] it's include!
asc = token_code[1];
var tokens = ReadCookie(asc).toString();
tokenValues = decodeURIComponent(tokens).split(',');
//loop through each category.
//hide every category and it's children
$("[data-token]").show();
$.each(tokenValues, function (index, value) {
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").hide();
});
}
is there an easier way to do this?
In the bottom of your code, were the comment says to show, it runs .hide().
Could that be a problem?
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").hide();

any sort of getElement(s)By---- function for getting a class by name, returns undefined

function getElsByClass(searchClass,node) {
if ( node == null )
node = document;
var classElements = [],
els = node.getElementsByTagName("div"),
elsLen = els.length,
pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"), i, j;
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
function getSong() {
console.log("getSong ran");
var songN = getElsByClass("info")[0], nmSong = getCookie();
console.log(songN);
songN = songN.getElementsByTagName("a");
songN = songN[0].innerText + " - " + songN[1].innerText;
if (nmSong != songN) {
setCookie(songN);
} else {
setCookie(songN);
}
sendSong(songN);
return songN;
}
setInterval(getSong(), 10000);
I've tried songN = document.getElemenetsByClassName("info"), and every combination I could find, and it will only run for maybe 30 seconds before it closes, I need it to run for hours, unattended...
I can run
var songN = getElsByClass("info")[0];
console.log(songN); //is actually defined when ran in Javascript Console in Chrome..
songN = songN.getElementsByTagName("a");
songN = songN[0].innerText + " - " + songN[1].innerText;
in Javascript console, and it returns exactly, what I'm trying to do, but if it runs as a userscript or after it's been injected into the web page, I get Uncaught TypeError: Cannot read property 'getElementsByTagName' of undefined, and I've tried to define it many different ways I found through searching google, and stackoverflow, I've ran the script on window.load, in the <head>, and tried to make it run in <body>.
getElsByClass() is my last attempt at it, it's not actually apart of my script, just a bit I tried from another script, tried shortening the name so it couldn't possibly conflict, but still nothing.
=== Update ===
Here is some more of the code..
function getCookie() {
console.log("getCookie ran");
var sname = "songname=", ca = document.cookie.split(';'), i = 0, c, t;
for (i; i < ca.length; i++) {
c = ca[i].trim();
if (c.indexOf(sname) == 0) {
t = c.substring(sname.length, c.length);
console.log(t);
return t;
}
}
return "";
}
function setCookie(cvalue) {
console.log("setCookie ran");
var d = new Date();
d.setTime(d.getTime() + 210000);//set it to expire in 3 minutes and 30 seconds from current time (this is average song time.)
document.cookie = "songname=" + cvalue + "; expires=" + d.toGMTString();
}

What is the best way to get a cookie by name in JavaScript?

I am using prototype and I can't find any built in extensions to set or retrieve cookies. After googling for a little bit, I see a few different ways to go about it. I was wondering what you think is the best approach for getting a cookie in JavaScript?
I use this routine:
function ReadCookie(name)
{
name += '=';
var parts = document.cookie.split(/;\s*/);
for (var i = 0; i < parts.length; i++)
{
var part = parts[i];
if (part.indexOf(name) == 0)
return part.substring(name.length)
}
return null;
}
Works quite well.
Anytime I need to access it, I use document.cookie, basically how it's outlined in that article. Caveat, I've never used prototype, so there may be easier methods there that you just haven't run across.
In case anyone else needs it, I've fixed up Diodeus's code to address PhiLho's concern about partial matches when trying to fetch a cookie value.
function getCookie(c_name) {
var nameEQ = c_name + '=';
var c_start = 0;
var c_end = 0;
if (document.cookie.substr(0, nameEQ.length) === nameEQ) {
return document.cookie.substring(nameEQ.length, document.cookie.indexOf(';', nameEQ.length));
} else {
c_start = document.cookie.indexOf('; ' + nameEQ);
if(c_start !== -1){
c_start += nameEQ.length + 2;
c_end = document.cookie.indexOf(';', c_start);
if (c_end === -1) {c_end = document.cookie.length;}
return document.cookie.substring(c_start, c_end);
}
}
return null;
}
I've recently also built a much more compact RegExp that should work as well:
function getCookie(c_name){
var ret = window.testCookie.match(new RegExp("(?:^|;)\\s*"+c_name+"=([^;]*)"));
return (ret !== null ? ret[1] : null);
}
I did some speed tests that seem to indicate that out of PhiLo, QuirksMode, and these two implementations the non-RegExp version (using indexOf is very fast, not a huge surprise) above is the fastest. http://jsperf.com/cookie-fetcher
I use this. It has been dependable:
function getCookie(c_name) {
if (document.cookie.length>0)
{
c_start=document.cookie.indexOf(c_name + "=")
if (c_start!=-1)
{
c_start=c_start + c_name.length+1
c_end=document.cookie.indexOf(";",c_start)
if (c_end==-1) c_end=document.cookie.length
return unescape(document.cookie.substring(c_start,c_end))
}
}
return ""
}

Categories

Resources