Issue #0: Contributing for the First Time

Before I start, I want to thank Firefox.

It is not often I get to be smug about my choice of browser. Usually, I have to go on the defensive about why I use Firefox, only for my reasons to fall on deaf ears and then jokingly be called a loser.

Not this time.

This week’s assignment is a continuation of last week’s. However, instead of working on our own notepad app, we had to work on our classmates’ work. It was an introduction to contributing on GitHub – issuing issues and pull requests, that sort of thing.

So why am I so thankful to Firefox?

Finding Bugs: Multi-Browser Testing

Making a simple notepad app does not require a lot of code. So when I was making mine and it refused to work while everyone around me had theirs working, I was confused. What was I doing wrong?

Turns out I was using Firefox.

Ok, the actual problem was with how Firefox treats the contentEditable attribute. When I deleted everything in the notepad, I could not type anything again, this was because Firefox does not set a minimum paragraph size; this meant that when the <div> was empty, the minimum paragraph size was 0, so I couldn’t type. Chrome doesn’t have that issue.

Code does not react the same way across all browsers. The bugs I found were because Firefox does not work the same way as Chrome. While my friends struggled to find bugs, I only had to load the application on my preferred browser and try to use it.

So again, thanks Firefox. You made this assignment significantly easier for me.

While in my case the application worked properly on one browser, I can’t say the same for the code I fixed. In Chrome, the code seemed like it worked, but in Firefox the feature was broken. It wasn’t until I tried to fix it for Firefox that I found out the feature was not properly working on Chrome either.

When creating web applications, try testing your code in different browsers. While you might not care about multi-browser compatibility, you might be able to notice something about your code that you were not aware of.

You can find what the bug was and how to fix it here.

Adding Features: Back again with Dark Mode

Links: Repository | Issue | Pull-Request | my-note

In my previous post, I mentioned my dislike of the lack of a dark mode option. So when the time came to add a feature, I decided that it would be fun to convince one of my classmates that it was a feature they needed.

It turns out it was a successful endeavor

While drwm-base had decided to use PaperCSS in his app, the process to add dark mode was not significantly different. I only needed to create a button to toggle the dark mode:

<div class="switch"> 
         Dark mode:
         <button class="inner-switch">OFF</span>
 </div>

Added the jquery library:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

And then the code needed to make it work.

 $(".inner-switch").on("click", function () {
                    if ($("body").hasClass("dark")) {
                        $("body").removeClass("dark");
                        $(".inner-switch").text("OFF");
                    } else {
                        $("body").addClass("dark");
                        $(".inner-switch").text("ON");
                    }

If you want a full step-by-step tutorial you can find it here.

The Other Side: Pull Request I received

Changing the save function to catch errors

Links: Contributor| Issue | Pull-Request

My original code would always alert the user that it saved. When I coded that, I assumed that the saving function would always work. But what if something went wrong and saving could not be completed? The user would still get notified that their text was saved.

What Neilon31 did, was add a case if an error occurs, so instead of:

function save() {
    fs.writeFile('/note', JSON.stringify(quill.getContents()));
}

function saveAlert(){
    save();
    alert("Saved!");
}

Which would never let the user know if something wrong happened, He changed it to this:

function saveFile() {
    fs.writeFile('/note', document.querySelector('#note').innerHTML, function(err) {
        if(err) {
            console.error('Error saving', err);
            return alert('Unable to Save!');
        }
        return alert('Saved!');
    });
}

A single function that handles errors.

Closing Thoughts

The more I work with GitHub and git, the more comfortable I feel working on open source projects. I found that it was rewarding helping my classmates make sure their code didn’t have bugs. One of my friends even joked that if a repository existed, I’d forked it – I found that if I found an issue, it was very likely someone else had the same one, so if I knew the fix, why not help out the other person too?

Receiving feedback and help from other users was great. I am far from an expert in JavaScript so having other people look over my code and find issues is a great resource.

Word Count: How I learned one regex was not enough

Links: Repository | Issue | Pull-Request | my-note

I encountered this bug while going through all of my classmates’ applications looking for one that didn’t work correctly in Firefox. It took a while, but I will say it was time well spent.

The Issue

I first noticed something was wrong when I deleted all of the content in the notepad. The word counter read 1. No matter how much I backspaced, the counter never changed to 0.

I then checked the application in Chrome. The word counter did not have that problem. It was at that moment I knew I wanted to fix that bug. How hard could it be? The last bug I fixed because it didn’t work on Firefox only took a line to fix.

Well, turns out that the function only appeared to work in Chrome and I needed to re-acquaintance myself with regular expressions. Do you know what “&nbsp ; ” means? Because now I do.

Bottom line: WordCount() was counting specials characters not visible to the user. (to see the full extend of the issue, checkout the link above)

The Code: WordCount()

function wordCount() {
     var count = 
     document.querySelector("#note").innerHTML.trim().replace(/  +/g, ' ').split(' ').length;
     if (document.querySelector("#note").innerHTML.length == 0) count = 0;
     document.querySelector("#wordNum").innerHTML = "Word Count: " + count;
}

So how the code worked was that it counted the number of spaces in #note after the content was trimmed and that would be the number of words.

The if statement would set the word counter to 0 if there was nothing in #note. This statement was needed because if split() finds nothing, it returns an empty string instead of an empty array. So even if there is nothing in #note, the length would always be one.

However, things start to go wrong, the more time you play with it. Because it counts spaces, it wouldn’t count words added after new lines. In chrome, multiple spaces become a non-breaking space ( &nbsp ; ), so they would not be removed by trim() and that meant they were added to the count. Other special characters that would be added to the count in Chrome were <br> and <div>, you can’t see them while typing, but they were present.

The Fix

  function wordCount() {
                var count = document.querySelector("#note").innerHTML.trim();
                count = count.replace(/ +/g, "");
                count = count.replace(/<[^>]*>/g, " ");
                count = count.replace(/\s+/g, " ");
                count = count.split(" ");
                var p = 0;
                for( var i = 0; i < count.length; i++){
                    if(count[i] == "")
                        ++p;
                }
                count = count.length - p;
               document.querySelector("#wordNum").innerHTML = "Word Count: " + count; 
            } 

What my code does is that it gets rid of all non-breaking white spaces, and it turns all tags(/<[^>]*>/) and whitespace characters (/\s+/) into spaces. Depending on the content, the split() will return an array with some empty strings, so the loop makes sure no empty strings are added to the count.

Final Thoughts

While the fix took me longer than I expected, it was rewarding to figure out what was wrong. After I issued a pull request to RyanWils, I decided to see if any other of my classmates had the same issue. What I found was that nearly everyone who had implemented the word count function had used the same buggy code for it. I opened issues for them too.

Sometimes open source can be helpful, but when you’re not careful, the same bug can spread across the web. How often do you go back to the place where you found the bit of code you took? How long would it take you to realize something in your app is wrong if you never meant to use your code for more than what an assignment called for? How many people will be affected by the code you write?