Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Thursday, April 22, 2021

HTML dialog Tag


dialog.html:

<html>

<body>

<button onclick="openDialog()">Open Dialog</button>

<dialog id="myDialog"><iframe src="dialogbox.html"></iframe></dialog>

<script>

function openDialog() {

  document.getElementById("myDialog").showModal();

}

</script>

</body>

</html>


dialogbox.html:

<html>

<body>

<button onclick="parent.document.getElementById('myDialog').close()">

Click to close

</button>

</body>

</html>

 

Tuesday, April 2, 2019

Disable JavaScript on browsers


Google Chrome
  1. Click on the vertical ellipsis button at the top-right corner of the browser.
  2. Select Settings from the menu.
  3. On the Settings page, input JavaScript into the Search bar and hit Enter.
  4. Click on Content Settings from the search result.
  5. Click on JavaScript from the Content Settings page
  6. There you can toggle the Allowed switch. Or you can set the URL you want to block or allow individually.
 Firefox
  1. Input about:config in the address bar and hit Enter.
  2. Acknowledge the I accept the risk! warning.
  3. Search for javascript.enabled.
  4. Double click the option to toggle it between true or false.
IE
  1. Click on the Gear icon at the top-right corner of the browser.
  2. Select Internet options from the menu.
  3. Select the Security tab.
  4. Select the Internet zone (or other zones depending on the web sites you plan to visit).
  5. Click on the Custom level... button.
  6. Scroll to the Scripting/Active scripting setting.
  7. Select Disable or Enable or Prompt to control how the browser handles JavaScripts.


Monday, March 25, 2019

JavaScript: Duplicate element IDs and duplicate function names


Consider this piece of code:

<html>
<body>
<button id='btn'>Button1</button>
<script>
  var bn1 = document.getElementById('btn');
  bn1.addEventListener('click', func);
 
  function func() {
    alert('func 1');
  }
</script>
<br>
<button id='btn'>Button2</button>
<script>
  var bn2 = document.getElementById('btn');
  bn1.addEventListener('click', func);
 
  function func() {
    alert('func 2');
  }
</script>
</body>
</html>


After this is loaded in a web browser, 2 buttons are displayed. When clicking on Button1, it will show both alerts "func 1" and "func 2". When clicking on Button 2, nothing will happen.

When there are multiple elements with the same ID, document.getElementById() always gets the same element.

Although 2 functions have the same name, they are different function entities and they are registered as different listeners for the target node. The name of the function is not important after addEventListener() is called.

Thursday, March 21, 2019

HTML: style and class


HTML inline styles can be replaced by using CSS class. For example, the following code:

<p id="p1" style="font-size:100px; color:blue;">Big blue</p>

can be rewritten into

<p id="p2" class="bigblue">Big blue</p>

by using a "bigblue" class defined in a linked CSS file:

.bigblue {
  font-size:100px;
  color:blue;
}


There is something we need to pay attention to if we want to dynamically hide and show an element with the style.display property. For example, if we want to hide the above "p1" element initially and later show it, we can do this with inline style:

<p id="p1" style="font-size:100px; color:blue; display:none;">Big blue</p>

<script type="text/javascript">
  // Later, we remove the style.display property to show the element.
  document.getElementById("p1").style.display = "";
</script>


However, for the other approach with CSS class, resetting style.display doesn't work:

.bigblue {
  font-size:100px;
  color:blue;
  display:none;
}


<p id="p2" class="bigblue">Big blue</p>

<script type="text/javascript">
  document.getElementById("p2").style.display = "";   // "p2" won't show up
</script>


We would need to explicitly set the style.display to its default value "inline" to make the element show up:

<script type="text/javascript">
  document.getElementById("p2").style.display = "inline";  

</script>

Tuesday, March 19, 2019

Replace CSS Expression with JavaScript


CSS Expression is only supported in IE7 and older versions. To make the web site using CSS Expression display properly in newer browsers, CSS Expression can be replaced with JavaScripts.

For example, the following code:

<table border='1'>
  <tr>
    <td style='width:10'>1</td>
    <td style='width:expression(body.clientWidth -10);'>2</td>
  </tr>
</table>

can be replaced into:

<table border='1'>
  <tr>
    <td style='width:10'>1</td>
    <td id='td2'>2</td>
  </tr>
</table>

<script type='text/javascript'>
  var elm = document.getElementById('td2');
  elm.style.width = document.body.clientWidth - 10;
</script>

Wednesday, March 13, 2019

JavaScript: Internet Explorer Event Handling


This is for event handling on different IE versions.

Dispatch an event at a specific element:

if (elemnt.dispatchEvent) {
  // IE9 and up
  var evtObj = document.createEvent('MouseEvents');
  evtObj.initEvent(event, true, true);
  elemnt.dispatchEvent(evtObj, true, true);
} else if (elemnt.fireEvent) {
  // Old versions of IE
  elemnt.fireEvent('on' + event);
}

Add the event listener for an element:

function myFunc() {
  // do something
}

if (elemnt.addEventListener) {
  // IE9 and up 
  elemnt.addEventListener(event, myFunc);
} else if (elemnt.attachEvent) {
  // Old versions of IE
  elemnt.attachEvent('on'+event, myFunc);
}

Sunday, April 8, 2012

To hide your Javascript code from the users


Sometimes you may want to hide or encrypt your Javascript code. We have an online tool JavaScript Compiler and Encoder that can encode your Javascript code to make it obfuscated so that it is hard to read by a human.

To use it, just paste your original source code into the *Your source code* box and click on the *GO* button. The source code will be sent to the Closure Compiler (by Google) online service to get compiled. The result will be shown in the *Compiled code* box. If your source code contains errors or warnings, the error or warning messages will be shown instead of the compiled code, and it will stop there. If your source code is good, the compiled code will be encoded and the result will be shown in the last *Encoded code* box.

If you know the warnings returned from the Closure Compiler is trivial and you can live with it -- not recommended, you can let the tool ignore the warnings by checking *Ignore Warnings*.

This tool helps to obfuscate your code. But you should know that because JavaScript code runs on the client side, it must be fully downloaded by the browser to run. That means the code will be in the users' machine and the determined users can still get your code.

This tool is not supported in the old browsers, e.g. Firefox 3.6. If it does not work on your browser, please try upgrade your browser. It does not work on IE 9. IE 10 starts to support XMLHttpRequest so most likely it could work on IE 10.

Sunday, February 26, 2012

Blogger widget: Recent comments by Readers


At the bottom of this page, you can see the live demo of the Recent Comments by Readers. It uses the Blogger Feed of the comments. (The URLs of Blogger Feed can be found here: http://support.google.com/blogger/bin/answer.py?hl=en&answer=97933.) I use the response in JSON format, so the URI is /feeds/comments/default?alt=json&callback=blogRecentComments12.

We need to implement a Javascript function blogRecentComments12(). This widget only shows the comments from the readers and hides the author's own comments. So in the function, we filter the name of the blog author. If you want to use the following code, you need to change the variable filteredAuthor12.

<script type="text/javascript">
var filteredAuthor12 = "YourName";
var numOfComments12 = 10;
</script>

<div style="text-transform:none;"><ul id="blogRecentCommentsElmt12"></ul></div>

<div style="font-size:80%;"><a href="http://www.toptip.ca">Recent Comments Widget</a></div>

<script type="text/javascript">

function blogRecentComments12(root)
{
   var elmt = document.getElementById("blogRecentCommentsElmt12");
   if (!elmt)
      return;

   var num = 0;

   var feed = root.feed;

   if (feed.entry.length > 0)
   {
      for (var i = 0; i < feed.entry.length; i++)
      {
         var entry = feed.entry[i];

         var title = entry.title.$t;

         title = title.replace(/&amp;/g, "&")
                         .replace(/&quot;/g, '"')
                         .replace(/&#39;/g, "'")
                         .replace(/&lt;/g, "<")
                         .replace(/&gt;/g, ">");

         var author = null;
         var authorUri = null;

         if (entry.author.length > 0)
         {
            author = entry.author[0].name.$t;
           
            if (entry.author[0].uri)
               authorUri = entry.author[0].uri.$t;

            if (author == filteredAuthor12)
               continue;
         }

         for (var j = 0; j < entry.link.length; j++)
         {
            if (entry.link[j].rel == "alternate")
            {
               var url = entry.link[j].href;

               if (url && url.length > 0 && title && title.length > 0)
               {
                  var liE = document.createElement("li");

                  var a1E = document.createElement("a");
                  a1E.href = url;
                  a1E.textContent = title;

                  liE.appendChild(a1E);

                  var txtE = document.createTextNode(" by ");
                  liE.appendChild(txtE);

                  if (author && author.length > 0)
                  {
                     var a2E = document.createElement("a");

                     if (authorUri)
                        a2E.href = authorUri;
                    
                     a2E.textContent = author;

                     liE.appendChild(a2E);
                  }

                  elmt.appendChild(liE);

                  num++;

                  if (num >= numOfComments12)
                     return;
               }

               break;
            }
         }
      }
   }
}

</script>

<br /><br />

<script src="/feeds/comments/default?alt=json&callback=blogRecentComments12">
</script>

Tuesday, January 17, 2012

Javascript: setting image width/height in pixels, cannot use "px"


The *img* element has its own width and height property. You can resize an image by setting its width and height property or by setting its style property, e.g.

   imageElement.width = "100";
      or
   imageElement.style.width = "100px";

They both resize the width of the image to 100 pixels.

You may notice that one is set with "px" at the end, the other is without. If you try the following code, you can find "px" is not needed in the 3rd case:

<html>
<head>
<script type="text/javascript">
function changeSize1()
{
  document.getElementById("b1").style.width="300px";
  document.getElementById("b1").style.height="300px";
}
function changeSize2()
{
  document.getElementById("b2").style.width="300";
  document.getElementById("b2").style.height="300";
}
function changeSize3()
{
  document.getElementById("b3").width="300px";
  document.getElementById("b3").height="300px";
}
function changeSize4()
{
  document.getElementById("b4").width="300";
  document.getElementById("b4").height="300";
}
</script>
</head>
<body>

Click the image to change size. <br /><br />
image 1: <img id="b1" onclick="changeSize1()" src="" /><br />
image 2: <img id="b2" onclick="changeSize2()" src="" /><br />
image 3: <img id="b3" onclick="changeSize3()" src="" /><br />
image 4: <img id="b4" onclick="changeSize4()" src="" /><br />

</body>
</html>

The code of the 3rd function:

  document.getElementById("b3").width="300px";
  document.getElementById("b3").height="300px";

will cause the size of the image becomes 0. "px" cannot be used with the width/height property of *img*.

Friday, January 6, 2012

Lightbox without jQuery -- soooooooo simple


Lightbox is like a modal dialog which usually pops up to display images. It looks fancy and more websites are now using it. Most of the tutorials on creating a Lightbox is by using jQuery. But the magic of Lightbox has nothing do with jQuery. It is the *CSS position property* that plays the key. All you need are two things:

1) a style sheet for the lightbox:
   .lightbox {
      position:fixed;
      top:0;
      left:0;
      width:100%;
      height:100%;
      background:rgba(0, 0, 0, .8);
   }

2) the lightbox:
   <div class="lightbox">
      <img src="any-image-url" />
   </div>

Those are the backbone of the lightbox.

Certainly, they are of no practical use yet. A real lightbox usually appears when the reader clicks on something, e.g. a button. Secondly, it looks much better if the image in the lightbox is centered. These are not special techniques for lightbox and there are tons of solutions. Here is one example.

To open and close the lightbox:

1) Assign the lightbox an ID and hide it when loaded; Clicking on it will close itself:
<div id="lightbox" class="lightbox" style="display:none"
      onclick="document.getElementById('lightbox').style.display='none';">
</div>

2) Add a button to show the lightbox:
<button onclick="document.getElementById('lightbox').style.display='inline';">
Show lightbox
</button>

To center the image in the lightbox:

Centering an element horizontally is easy while doing it vertically is very tricky. Since the CSS vertical-align property works only in table cells, we use a *table* to wrap the content in the lightbox.

The style sheet for the table:

.lightbox_table {
    width:100%;
    height:100%;
}

.lightbox_table_cell {
    vertical-align:middle;
}

The table inside the lightbox:

<table class="lightbox_table">
<tr>
<td class="lightbox_table_cell" align="center">

<div id="lightbox_content" style=
       "width:300px; background-color:white; border:5px solid black;">

   <img src="any-image-url" />

</div>

</td>
</tr>
</table>

You can see a live example by click on the following button.



Here is the whole thing of this example.

<html>
<head>
<style>

.lightbox {
    position:fixed;
    top:0;
    left:0;
    width:100%;
    height:100%;
    background:rgba(0, 0, 0, .8);
}

.lightbox_table {
    width:100%;
    height:100%;
}

.lightbox_table_cell {
    vertical-align:middle;
}

</style>
</head>

<body>
<button onclick="document.getElementById('lightbox').style.display='inline';">
Show lightbox
</button>

<!-- LIGHTBOX CODE BEGIN -->
<div id="lightbox" class="lightbox" style="display:none"
      onclick="document.getElementById('lightbox').style.display='none';">

   <table class="lightbox_table">
   <tr>
   <td class="lightbox_table_cell" align="center">
      <div id="lightbox_content" style=
            "width:300px; background-color:white; border:5px solid black;">

         <p>Click anywhere to close the lightbox.</p>
         <p>Use Javascript to insert anything here.</p>

      </div>
   </td>
   </tr>
   </table>

</div>
<!-- LIGHTBOX CODE END -->

</body>
</html>


Tuesday, December 13, 2011

Share Buttons Bar


As you can see in the bottom left corner of this page, the Share Buttons Bar embeds the most popular share buttons from Internet. Your readers can shrink or expand the Bar by click on the rightmost button.

If you are interested to add the Share Buttons Bar to your web site, it is very simple. Just copy the following two pieces of code to the appropriate place. Before doing it, you should certainly make a backup first.

Step 1: Copy this piece of code just before tag </head>
<!-- Share Buttons Bar (C) TopTip.ca - header - BEGIN -->
<style type='text/css'>
.shr12_buttons_bar {position:fixed; bottom:0px; left:0px; z-index:100; background-color:white; text-align:left; border:1px solid gray}
.shr12_button {display:inline-block; vertical-align:middle; height:20px; padding:2px 10px;}
.shr12_button_compact {display:inline-block; vertical-align:middle; height:20px; padding:2px;}
.shr12_csrptr {cursor:pointer;}
</style>

<script type='text/javascript'>
//<![CDATA[
function shr12_add_script(d, id, src)
{
  if(!d.getElementById(id)){
    var fjs=d.getElementsByTagName('script')[0];
    var js=d.createElement('script'); js.id=id; js.src=src;
    js.type = 'text/javascript'; js.async = false; /* "true" does not work well */
    fjs.parentNode.insertBefore(js,fjs);
  }
}

function shr12_buttons_bar_expand()
{
  document.getElementById('shr12_buttons').style.display='inline';
  document.getElementById('shr12_buttons_min').style.display='none';
}

function shr12_buttons_bar_shrink()
{
  document.getElementById('shr12_buttons').style.display='none';
  document.getElementById('shr12_buttons_min').style.display='inline';
}
//]]>
</script>
<!-- Share Buttons Bar (C) TopTip.ca - header - END -->
Step 2: Copy this piece of code right before tag </body>
<!-- Share Buttons Bar (C) TopTip.ca - body - BEGIN -->
<div class='shr12_buttons_bar' id='shr12_buttons_min' style='display:none;'>
<span class='shr12_button' id='shr12_gplusone_min'>
<g:plusone size='medium' annotation='none'/>
</span>
<b class='shr12_button shr12_csrptr' onclick='shr12_buttons_bar_expand()'> &gt; </b>
</div>

<div class='shr12_buttons_bar' id='shr12_buttons'>
<span class='shr12_button_compact' id='shr12_gplusone'>
<g:plusone size='medium'/>
<script type="text/javascript"> //<![CDATA[
shr12_add_script(document, 'gplusone-button-script', 'https://apis.google.com/js/plusone.js');
//]]> </script>
</span>
<span class='shr12_button' id='shr12_facebook'>
<span id="fb-root"></span>
<script type="text/javascript"> //<![CDATA[
shr12_add_script(document, 'facebook-jssdk', '//connect.facebook.net/en_US/all.js#xfbml=1');
//]]> </script>
<div class='fb-like' data-layout='button_count' data-send='false' data-show-faces='false'> </div>
</span>
<span class='shr12_button_compact' id='shr12_twitter'>
<a href="https://twitter.com/share" class="twitter-share-button" data-lang="en">Tweet</a>
<script type="text/javascript"> //<![CDATA[
shr12_add_script(document, 'twitter-wjs', '//platform.twitter.com/widgets.js');
//]]> </script>
</span>
<span class='shr12_button' id='shr12_stumbleupon'>
<script src='http://www.stumbleupon.com/hostedbadge.php?s=1'/>
</span>
<span class='shr12_button' id='shr12_digg'>
<script type="text/javascript"> //<![CDATA[
shr12_add_script(document, 'digg-button-script', 'http://widgets.digg.com/buttons.js');
//]]> </script>
<a class='DiggThisButton DiggCompact'/>
</span>
<span class='shr12_button' id='shr12_reddit'>
<script type="text/javascript" src="http://www.reddit.com/static/button/button1.js"></script>
</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a class='shr12_button' href='http://www.toptip.ca/2011/12/share-buttons-bar.html'>Get This</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b class='shr12_button shr12_csrptr' onclick='shr12_buttons_bar_shrink()'> &lt; </b>
</div>

<script type="text/javascript"> //<![CDATA[
setTimeout(shr12_buttons_bar_shrink, 10000);
//]]> </script>
<!-- Share Buttons Bar (C) TopTip.ca - body - END -->

It is just that simple. If you like it, please recommend it to your friends or on your web site. It would be much appreciated if you can post our link on your site to let your readers know the origin of this widget is from http://www.toptip.ca/2011/12/share-buttons-bar.html.

Friday, May 13, 2011

A very simple example of Internet Explorer addon development


This is not a complete tutorial. It shows how easy it is to build an IE addon/extension in just 5 minutes. And it does not stop you from building a far more complex addon with the other mechanisms.

This example adds a menu item to the default context menu of IE. When right click on IE, the user can see the new menu item and click on it. A dialog pops up showing the title of the Web page you are viewing.

Adding extensions to IE usually requires adding keys to the Windows registry. We prepare a REG file to add the keys to the Windows registry. In our REG file, we also specify the location of an HTML file which contains a JavaScript to run when our context menu item is clicked.

Here is the step-by-step of building the simplest IE addon:

1. Create a new folder in disk C:, e.g. C:\YBPM\

2. Use your favorite editor to create 3 files in that folder, e.g.
      C:\YBPM\ybpm.reg
      C:\YBPM\ybpm_rm.reg
      C:\YBPM\ybpm.html

   ybpm.reg is the REG file that create the menu item on the default context menu. ybpm_rm.reg is the uninstaller which remove the menu item from the default context menu. ybpm.html contains the script that runs when the context menu item is clicked.

   *** file ybpm.reg***
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\&YouTube Bulk Player Mate]
@="C:\\YBPM\\ybpm.html"
"Contexts"=dword:00000001
"Flags"=dword:00000001


Note: it adds a key "YouTube Bulk Player Mate" (don't mind the name, it is a piece of code from one of my open source projects. You should use your own one.) to the registry to create an item in the context menu. The default value (@) of the key is set to the URL of the file that contains the script that will run when the menu item is clicked.

   *** file ybpm_rm.reg ***
Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\&YouTube Bulk Player Mate]


Note: it simply deletes the key that was generated by ybpm.reg.

   *** file ybpm.html ***
<SCRIPT>

var parentwin = external.menuArguments;
var doc = parentwin.document;
var ttl = doc.getElementsByTagName("title");

if (ttl.length > 0)
   document.write(ttl[0].innerHTML);

</SCRIPT>


Note: external.menuArguments lets you access the window object of the current page.

3. Restart your Internet Explorer. Right click on any page. You will see "YouTube Bulk Player Mate" item in the context menu. Click on it and you will see a pop-up window showing the title of the current page.

If you are interested to see a live example, you can find the YouTube Bulk Player Mate addon for IE here.

Monday, January 31, 2011

What happened to the Chrome extension Boss Key and Button


Just got a comment on the post Google Chrome extension Boss Key and Button, and knew that the extension's Options page stopped working. After some investigation, it turned out that the new version of Google Chrome does not support the syntax:
        <script src="bossknb.js" />

We have to change it into:
        <script src="bossknb.js"></script>
       
It was not only Google's fault. Google did broadcast an Email in early November to reveal this bug in Google Chrome -- which Google promised to fix ASAP.

As people are asking for a fix for the extension, we are going to release an update for this issue ASAP -- should be much sooner than Chrome.

BTW, is Chrome mature enough to compete with Firefox?


Wednesday, April 21, 2010

Online unit converter


Many of the supermarkets here are playing tricks on the price tags. While the price tag displays $x.xx/lb, the receipt shows the price in dollars per kilograms. As a customer, we are always confused and hard to remember the listed price when we are reading the receipt. But why the supermarkets do that? 99 cents per pounds looks quite attractive on the price tag. People nowadays do not expect too much from a buck or so. When you enter a supermarket and see that one dollar, even less a dollar, can buy this, that and a lot, you cannot help buying all those good deals. Not until you get home and read the receipt, you find out it is actually $2.18 per kilogram. No! It is not under a buck. It is more than 2 bucks!

Well, you and I all know they are the same things. It is just a trick of the unit conversion. I wrote a little JavaScript program Unit Converter to help easily comparing things in different units. It does not cover everything. Instead, it just collect some of the most useful units we may use in daily basis.

For example, when you are travelling outside the country, you may not know whether the gas is too expensive if the price is listed as per litre instead of gallon, or vice versa. And you may not know whether you should wear T-shirt or coat if the temperature is forecast in a different unit of Fahrenheit or Celsius.

Bookmark this little online tool to make life simple -- Unit Converter.

Tuesday, March 30, 2010

Firefox extension programming: play sound


A Firefox extension can play sound with the nsISound interface. In my next release of the extension Take A Break, I will add the sound to remind the user of a break. The interface is very easy to use.

1. Create a sound instance.
   sound = Components.classes["@mozilla.org/sound;1"]
            .createInstance(Components.interfaces.nsISound);
2. Beep.
   sound.beep();
That is how simple it can be. The Take A Break extension beeps every 3 seconds during the short break -- while the icon is flashing. So the user can close his/her eyes for a rest. When the beeping stops, the user can know the short break is over.

To do beeping every 3 seconds, we use the setTimeout() function. First, define a function doBeep().
   function doBeep()
   {
      if (sound)   // the "sound" instance we created
      {
         // Get the current time in milli-seconds.
         var currentTimeMs = (new Date()).getTime();

         // flashEndTimeMs tells when the short break will finish.
         // flashEndTimeMs was set before this function is called.
         if (currentTimeMs > flashEndTimeMs)
         {
            // Flashing ends. Stop beeping.
            beepTimer = null;
            return;
         }

         sound.beep();

         // restart timer.
         // After 3 seconds, this function is called back again.
         beepTimer = window.setTimeout(function(){ doBeep(); },
                        3000);   // 3 seconds
      }
   }
As you can see, inside the function doBeep(), we register itself as a callback function for the 3 seconds timeout event. So doBeep() runs every 3 seconds until the short break ends.

Secondly, when it is time for the short break, we call the function doBeep() to start the first beeping.
   // Set the end time for the short break.
   var currentTimeMs = (new Date()).getTime();
   flashEndTimeMs = secOfFlash * 1000 + currentTimeMs;

   // Start flashing and beeping.
   doFlash();
   doBeep();
This feature will be released in version 1.1 of Take A Break. The sample code here is modified a little to make it more understandable.

Friday, February 19, 2010

JavaScript: trim leading or trailing spaces from a string


There is no built-in function to remove leading or trailing spaces from a string in JavaScript. To do that, we can use the replace() method of the String object.

The syntax of String's replace() method is:
string.replace(regexp/substr,newstring);
The first parameter can be a regular expression. The second parameter is a new string to replace what the regular expression matches in the string. So to trim the leading or trailing spaces, we can do this:
mystring = mystring.replace(/^\s+|\s+$/g, "");
The first parameter /^\s+|\s+$/g is a regular expression that matches the leading or trailing white-space characters. Let us break it down to see what it means:
  • \s matches a white-space character;
  • + matches the preceding element one or more times, so \s+ matches 1 or more white-space characters;
  • ^ matches the starting position of the string, so ^\s+ matches 1 or more leading white-space characters;
  • $ matches the ending position of the string, so \s+$ matches 1 or more trailing white-space characters;
  • | means or, so ^\s+|\s+$ matches 1 or more leading or trailing white-space characters;
  • /.../ means search;
  • g means global, so it will continue and search for the trailing white-space characters after it have found the leading white-space characters.
When a pattern is found in mystring, i.e. leading or trailing white-space characters are found, they will be replaced with an empty string "". The result? They are trimmed.

Friday, November 6, 2009

Javascript/Firefox: context menu popup


The context menu of Firefox behaves differently between the Windows and Linux platforms. On Linux, the context menu pops up as soon as you press down the right button of the mouse; While on Windows, it shows when you press down and release the right button.

The Linux style behavior makes it difficult for an extension to capture and hack the mousedown event. We can do a little hack to emulate the Windows style behavior on the Linux platform.

The idea is that we capture the mousedown event and suppress the context menu. When the user release the mouse button, we capture the mouseup event and fire a fake contextmenu event.

Here is the demo source code.


1. Capture the mousedown event and suppress the context menu.

1.1 Capture the mousedown event
addEventListener("mousedown", myMouseDown, true);

function myMouseDown(event)
{
   if (2 == event.button)    // right-click
   {
      if (navigator.platform != "Win32")   // No need for Windows
      {
         // Capture the contextmenu event.
         addEventListener("contextmenu", myNoContextMenu, true);

         // remove the listener right after to avoid mess up the other
         // contextmenu events.
         setTimeout(function(){ removeEventListener("contextmenu", myNoContextMenu, true); }, 0);
      }
   }
}

1.2 Suppress the context menu
function myNoContextMenu(event)
{
   // Prevent the default action, i.e. context menu poping up
   event.preventDefault();
   event.stopPropagation();
}


2. Capture the mouseup event and pop up the context menu.

1.1 Capture the mouseup event
addEventListener("mouseup", myMouseUp, true);

function myMouseUp(event)
{
   if (2 == event.button)   // right-click
   {
      myShowContextMenu(event);
   }
}


1.2 Pop up the context menu
function myShowContextMenu(event)
{
   if (navigator.platform == "Win32")
      return;  // on Window context menu is already shown on mouseup.

   // create a contextmenu event.
   var newEv = event.view.document.createEvent("MouseEvents");
   newEv.initMouseEvent("contextmenu", true, true, event.view, 1,
             event.screenX, event.screenY, event.clientX, event.clientY,
             false, false, false, false, 2, null);

   // fire the new event.
   event.originalTarget.dispatchEvent(newEv);
}

Thursday, October 29, 2009

Javascript/Firefox: context menu popup


Note: This solution has some side-effects. A better one is provided in my another post here.

The context menu of Firefox behaves differently between the Windows and Linux platform. On Linux, the context menu pops up as soon as you press down the right button of the mouse; While on Windows, it shows after you press down and release the right button.

We can change the Linux style behavior by doing a little hack.

1. Capture the mousedown event and suppress the context menu.

1.1 Capture the mousedown event

addEventListener("mousedown", myMouseDown, true);

function myMouseDown(event)
{
   if (2 == event.button)
   {
      // Capture the pop-up event of the context menu.
      addEventListener("popupshowing", myNoContextMenu, true);
   }
}
1.2 Suppress the context menu

function myNoContextMenu(event)
{
   // Prevent the default action, i.e. popping up
   event.preventDefault();

   // Remove the event handler because we don't want to mess up the
   // popupshowing events triggered by others.
   removeEventListener("popupshowing", myNoContextMenu, true);
}
2. Capture the mouseup event and pop up the context menu.

1.1 Capture the mouseup event

addEventListener("mouseup", myMouseUp, true);

function myMouseUp(event)
{
   if (2 == event.button)
   {
      myShowContextMenu(event);
   }
}
1.2 Pop up the context menu

function myShowContextMenu(event)
{
   if (navigator.platform == "Win32")
      return;  // on Window context menu is already shown on mouseup.

   document.popupNode = event.originalTarget;
   var cm = document.getElementById("contentAreaContextMenu");
   cm.openPopupAtScreen(event.screenX, event.screenY, true);

   // Cancel the event.
   event.preventDefault();
   event.stopPropagation();
}
 
Get This <