Jump to content

Very, very confusing problem


Fmdpa

Recommended Posts

I am in the middle of an extremely confusing problem. My script is acting very unnaturally. This is continued work on my Opera extension so keep that in mind as you analyze the code. Things like HTML5 local storage (the "prefs" object is my shorthand clone of the local storage object) and JSON parsing are supported, so it is highly unlikely that the problem is related to that. Here's my problem. The problem lies in the conditional statements near the end of my code. First, I put that "return false" statement at the very end to prevent the form from submitting. The first time I submit the form it works fine. I fill the field from which the "word" variable gets its value with something that will pass the "else if" condition. The first time, "blacklist includes" is logged like it is supposed to be. The second time you submit the form (remember, no page reload) the else{} code is executed. As you can see, I even logged a test with the else if() conditions, and it returned true! How in the world is it just ignoring that else if() condition???Here's the relevant part of my code (and more, probably):

function Whitelist() { 				this.words = JSON.parse(prefs.whitelist) // parse the comma separated words 								Whitelist.prototype.remove = function(word) {					this.words = this.words.deleteItem(word)					widget.preferences.whitelist = JSON.stringify(this.words)		// assign the whitelist array to the whitelist local storage variable					this.joined_whitelist = this.words.join(', ')								 // update "whitelist" array				}								Whitelist.prototype.add = function(word) {					word = word.replace(/,/g, '')										for (i = 0; i < this.words.length; i++ ) {						if ( this.words[i].toLowerCase() == word.toLowerCase() ) return // exit the function if the word being added is found in the whitelist					}					this.words.push(word)															 // add word to the whitelist array					widget.preferences.whitelist = JSON.stringify(this.words)		// assign the whitelist array to the whitelist local storage variable					this.joined_whitelist = this.words.join(', ')								 // update "whitelist" array				}								Whitelist.prototype.includes = function(word) {					for (i = 0; i < this.words.length; i++ ) {						if ( this.words[i].toLowerCase() == word.toLowerCase() ) return true // exit the function if the word being added is found in the whitelist					}										return false				}			}						/* blacklist object */						function Blacklist() { 				this.words = JSON.parse(prefs.blacklist) // parse the comma separated words 								this.remove = function(word) {					this.words = this.words.deleteItem(word)					widget.preferences.blacklist = JSON.stringify(this.words)		// assign the whitelist array to the whitelist local storage variable					this.joined_blacklist = this.words.join(', ')								 // update "whitelist" array				}								this.add = function(word) {					word = word.replace(/,/g, '')										for (i = 0; i < this.words.length; i++ ) {						if ( this.words[i].toLowerCase() == word.toLowerCase() ) return // exit the function if the word being added is found in the whitelist					}					this.words.push(word)															 // add word to the whitelist array					widget.preferences.blacklist = JSON.stringify(this.words)		// assign the whitelist array to the whitelist local storage variable					this.joined_blacklist = this.words.join(', ')								 // update "whitelist" array				}								this.includes = function(word) {					for (i = 0; i < this.words.length; i++ ) {						if ( this.words[i].toLowerCase() == word.toLowerCase() ) return true // exit the function if the word being added is found in the whitelist					}										return false				}			}search_form = $('#search_form') search_form.onsubmit = function() {				word = this.search.value.replace(/,/g, '') // remove commas from the value								if (word == '') return false// this is the problematic code:				if ( whiteList.includes(word) ) { // check first if the word is in the whitelist					console.log('whitelist includes')				} else if (window.dirtyList.test(word) || blackList.includes(word) ) { // check if the submitted word matches the word blacklist					console.log('blacklist includes')				} else {					console.log(window.dirtyList.test(word) || blackList.includes(word)) // returns true!!!										console.log('blacklist doesn\'t include')		  				}								return false			}

Link to comment
Share on other sites

Hmm, I've never seen the convention of prototyping a function object when inside the function.edit: you have two global declarations of the variable word.

search_form.onsubmit = function() {				word = this.search.value.replace(/,/g, '') // remove commas from the value

Whitelist.prototype.add = function(word) {					word = word.replace(/,/g, '')

I would advocate either putting var before both of them or changing their names. It would be preferable to make them local to their scope, so I would advocate the var method however.

Link to comment
Share on other sites

Thanks for noticing that. I fixed the clashing globals and removed the prototyping and it is doing something different now. Before if I submitted the form continuously it would log this:

blacklist includestrueblacklist doesn't includeblacklist includestrueblacklist doesn't includeblacklist includestrueblacklist doesn't include

Now it does this:

blacklist includestrueblacklist doesn't includetrueblacklist doesn't includetrueblacklist doesn't includetrueblacklist doesn't includetrueblacklist doesn't include

etc.Any ideas what could be wrong now?

Link to comment
Share on other sites

If this is false:} else if (window.dirtyList.test(word) || blackList.includes(word) ) {and then this shows true:console.log(window.dirtyList.test(word) || blackList.includes(word))then it sounds like blackList.includes is modifying the value of the word variable. It sounds like you're not scoping your variables correctly.

Link to comment
Share on other sites

I haven't run it, but scope is exactly the thing I'd look at. The word identifier is used in so many contexts it's hard to know if it's the global version or the local one. Maybe the interpreter can keep it more clear than I can. Dunno.

Link to comment
Share on other sites

I changed the conditional to this:

word.match(window.dirtyList.test) || blackList.includes(word)

And it works fine! I fixed all of the scope issues I could find as well.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...