| Index: chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
 | 
| diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
 | 
| index 1c0121f32e7712e93a71214889de229d68cd5764..4451240040d1b5a36f642cd737a91d8e85bad816 100644
 | 
| --- a/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
 | 
| +++ b/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html
 | 
| @@ -1,381 +1,12 @@
 | 
|  <!DOCTYPE html>
 | 
|  <html>
 | 
| -<head>
 | 
| -<style>
 | 
| -body {
 | 
| -  font-family: helvetica, arial, sans-serif;
 | 
| -  font-size: 12px;
 | 
| -  overflow: hidden;
 | 
| -}
 | 
| -
 | 
| -a {
 | 
| -  color:#0000CC;
 | 
| -  text-decoration: underline;
 | 
| -  cursor: pointer;
 | 
| -}
 | 
| -
 | 
| -.open_box {
 | 
| -  display: block;
 | 
| -  overflow: hidden;
 | 
| -  margin-right: 4px;
 | 
| -  margin-top: 2px;
 | 
| -  height: 12px;
 | 
| -  width: 12px;
 | 
| -  float: left;
 | 
| -  clear: left;
 | 
| -  background-image: url(sprite_arrows.gif);
 | 
| -  background-position: 0px -24px;
 | 
| -  cursor: pointer;
 | 
| -}
 | 
| -
 | 
| -.opened .open_box {
 | 
| -  background-position:-12px -24px;
 | 
| -}
 | 
| -
 | 
| -.item {
 | 
| -  padding: 2px 0px;
 | 
| -}
 | 
| -
 | 
| -.item_title {
 | 
| -  display: block;
 | 
| -  min-width: 300px;
 | 
| -  padding-left: 15px;
 | 
| -  cursor: pointer;
 | 
| -}
 | 
| -
 | 
| -.item_desc {
 | 
| -  min-width: 500px;
 | 
| -  height: 0px;
 | 
| -  display: block;
 | 
| -  border: none;
 | 
| -  padding: 0px;
 | 
| -  margin: 0px;
 | 
| -  -webkit-transition: height 0.2s ease-out;
 | 
| -}
 | 
| -
 | 
| -#title {
 | 
| -  display: block;
 | 
| -  margin-left: auto;
 | 
| -}
 | 
| -
 | 
| -.error {
 | 
| -  white-space: nowrap;
 | 
| -  color: red;
 | 
| -}
 | 
| -
 | 
| -.more {
 | 
| -  display: block;
 | 
| -  text-align: right;
 | 
| -  padding-top: 20px;
 | 
| -  padding-right: 10px;
 | 
| -  color: #88C;
 | 
| -}
 | 
| -
 | 
| -</style>
 | 
| -<script id="iframe_script">
 | 
| -function reportHeight() {
 | 
| -  var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
 | 
| -  parent.postMessage(msg, "*");
 | 
| -}
 | 
| -
 | 
| -function frameLoaded() {
 | 
| -  var links = document.getElementsByTagName("A");
 | 
| -  for (i = 0; i < links.length; i++) {
 | 
| -    var class = links[i].className;
 | 
| -    if (class != "item_title" && class != "open_box") {
 | 
| -      links[i].addEventListener("click", showStory);
 | 
| -    }
 | 
| -  }
 | 
| -  window.addEventListener("message", messageHandler);
 | 
| -}
 | 
| -
 | 
| -function showStory(event) {
 | 
| -  var href = event.currentTarget.href;
 | 
| -  parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
 | 
| -  event.preventDefault();
 | 
| -}
 | 
| -
 | 
| -function messageHandler(event) {
 | 
| -  reportHeight();
 | 
| -}
 | 
| -
 | 
| -</script>
 | 
| -<script>
 | 
| -// Feed URL.
 | 
| -var feedUrl = 'http://news.google.com/?output=rss';
 | 
| -
 | 
| -// The XMLHttpRequest object that tries to load and parse the feed.
 | 
| -var req;
 | 
| -
 | 
| -function main() {
 | 
| -  req = new XMLHttpRequest();
 | 
| -  req.onload = handleResponse;
 | 
| -  req.onerror = handleError;
 | 
| -  req.open("GET", feedUrl, true);
 | 
| -  req.send(null);
 | 
| -}
 | 
| -
 | 
| -// Handles feed parsing errors.
 | 
| -function handleFeedParsingFailed(error) {
 | 
| -  var feed = document.getElementById("feed");
 | 
| -  feed.className = "error";
 | 
| -  feed.innerText = "Error: " + error;
 | 
| -}
 | 
| -
 | 
| -// Handles errors during the XMLHttpRequest.
 | 
| -function handleError() {
 | 
| -  handleFeedParsingFailed('Failed to fetch RSS feed.');
 | 
| -}
 | 
| -
 | 
| -// Handles parsing the feed data we got back from XMLHttpRequest.
 | 
| -function handleResponse() {
 | 
| -  var doc = req.responseXML;
 | 
| -  if (!doc) {
 | 
| -    handleFeedParsingFailed("Not a valid feed.");
 | 
| -    return;
 | 
| -  }
 | 
| -  buildPreview(doc);
 | 
| -}
 | 
| -
 | 
| -// The maximum number of feed items to show in the preview.
 | 
| -var maxFeedItems = 5;
 | 
| -
 | 
| -// Where the more stories link should navigate to.
 | 
| -var moreStoriesUrl;
 | 
| -
 | 
| -function buildPreview(doc) {
 | 
| -  // Get the link to the feed source.
 | 
| -  var link = doc.getElementsByTagName("link");
 | 
| -  var parentTag = link[0].parentNode.tagName;
 | 
| -  if (parentTag != "item" && parentTag != "entry") {
 | 
| -    moreStoriesUrl = link[0].textContent;
 | 
| -  }
 | 
| -
 | 
| -  // Setup the title image.
 | 
| -  var images = doc.getElementsByTagName("image");
 | 
| -  var titleImg;
 | 
| -  if (images.length != 0) {
 | 
| -    var urls = images[0].getElementsByTagName("url");
 | 
| -    if (urls.length != 0) {
 | 
| -      titleImg = urls[0].textContent;
 | 
| -    }
 | 
| -  }
 | 
| -  var img = document.getElementById("title");
 | 
| -  // Listen for mouse and key events
 | 
| -  if (titleImg) {
 | 
| -    img.src = titleImg;
 | 
| -    if (moreStoriesUrl) {
 | 
| -      document.getElementById("title_a").addEventListener("click", 	                                                     moreStories);
 | 
| -      document.getElementById("title_a").addEventListener("keydown",
 | 
| -                                         function(event) {
 | 
| -                                           if (event.keyCode == 13) {
 | 
| -                                             moreStories(event);
 | 
| -                                           }});
 | 
| -    }
 | 
| -  } else {
 | 
| -    img.style.display = "none";
 | 
| -  }
 | 
| -
 | 
| -  // Construct the iframe's HTML.
 | 
| -  var iframe_src = "<!doctype html><html><head><script>" +
 | 
| -                   document.getElementById("iframe_script").textContent + "<" +
 | 
| -                   "/script></head><body onload='frameLoaded();' " +
 | 
| -                   "style='padding:0px;margin:0px;'>";
 | 
| -
 | 
| -  var feed = document.getElementById("feed");
 | 
| -  // Set ARIA role indicating the feed element has a tree structure
 | 
| -  feed.setAttribute("role", "tree");
 | 
| -
 | 
| -  var entries = doc.getElementsByTagName('entry');
 | 
| -  if (entries.length == 0) {
 | 
| -    entries = doc.getElementsByTagName('item');
 | 
| -  }
 | 
| -  var count = Math.min(entries.length, maxFeedItems);
 | 
| -  for (var i = 0; i < count; i++) {
 | 
| -    item = entries.item(i);
 | 
| -
 | 
| -    // Grab the title for the feed item.
 | 
| -    var itemTitle = item.getElementsByTagName('title')[0];
 | 
| -    if (itemTitle) {
 | 
| -      itemTitle = itemTitle.textContent;
 | 
| -    } else {
 | 
| -      itemTitle = "Unknown title";
 | 
| -    }
 | 
| -
 | 
| -    // Grab the description.
 | 
| -    var itemDesc = item.getElementsByTagName('description')[0];
 | 
| -    if (!itemDesc) {
 | 
| -      itemDesc = item.getElementsByTagName('summary')[0];
 | 
| -      if (!itemDesc) {
 | 
| -        itemDesc = item.getElementsByTagName('content')[0];
 | 
| -      }
 | 
| -    }
 | 
| -    if (itemDesc) {
 | 
| -      itemDesc = itemDesc.childNodes[0].nodeValue;
 | 
| -    } else {
 | 
| -      itemDesc = '';
 | 
| -    }
 | 
| -
 | 
| -    var item = document.createElement("div");
 | 
| -    item.className = "item";
 | 
| -    var box = document.createElement("div");
 | 
| -    box.className = "open_box";
 | 
| -    box.addEventListener("click", showDesc);
 | 
| -    // Disable focusing on box image separately from rest of tree item
 | 
| -    box.tabIndex = -1;
 | 
| -    item.appendChild(box);
 | 
| -
 | 
| -    var title = document.createElement("a");
 | 
| -    title.className = "item_title";
 | 
| -    // Give title an ID for use with ARIA
 | 
| -    title.id = "item" + i;
 | 
| -    title.innerText = itemTitle;
 | 
| -    title.addEventListener("click", showDesc);
 | 
| -    title.addEventListener("keydown", keyHandlerShowDesc);
 | 
| -    // Update aria-activedescendant property in response to focus change
 | 
| -    // within the tree
 | 
| -    title.addEventListener("focus", function(event) {
 | 
| -                                      feed.setAttribute(
 | 
| -                                        "aria-activedescendant", this.id);
 | 
| -                                    });
 | 
| -    // Enable keyboard focus on the item title element
 | 
| -    title.tabIndex = 0;
 | 
| -    // Set ARIA role role indicating that the title element is a node in the
 | 
| -    // tree structure
 | 
| -    title.setAttribute("role", "treeitem");
 | 
| -    // Set the ARIA state indicating this tree item is currently collapsed.
 | 
| -    title.setAttribute("aria-expanded", "false");
 | 
| -    // Set ARIA property indicating that all items are at the same hierarchical
 | 
| -    // level (no nesting)
 | 
| -    title.setAttribute("aria-level", "1");
 | 
| -    item.appendChild(title);
 | 
| -
 | 
| -    var desc = document.createElement("iframe");
 | 
| -    desc.scrolling = "no";
 | 
| -    desc.className = "item_desc";
 | 
| -    // Disable keyboard focus on elements in iFrames that have not been
 | 
| -    // displayed yet
 | 
| -    desc.tabIndex = -1;
 | 
| -
 | 
| -    item.appendChild(desc);
 | 
| -    feed.appendChild(item);
 | 
| -
 | 
| -    // The story body is created as an iframe with a data: URL in order to
 | 
| -    // isolate it from this page and protect against XSS.  As a data URL, it
 | 
| -    // has limited privileges and must communicate back using postMessage().
 | 
| -    desc.src="data:text/html," + iframe_src + itemDesc + "</body></html>";
 | 
| -  }
 | 
| -
 | 
| -  if (moreStoriesUrl) {
 | 
| -    var more = document.createElement("a");
 | 
| -    more.className = "more";
 | 
| -    more.innerText = "More stories \u00BB";
 | 
| -    more.tabIndex = 0;
 | 
| -    more.addEventListener("click", moreStories);
 | 
| -    more.addEventListener("keydown", function(event) {
 | 
| -                                       if (event.keyCode == 13) {
 | 
| -                                         moreStories(event);
 | 
| -                                       }});
 | 
| -    feed.appendChild(more);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -// Show |url| in a new tab.
 | 
| -function showUrl(url) {
 | 
| -  // Only allow http and https URLs.
 | 
| -  if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
 | 
| -    return;
 | 
| -  }
 | 
| -  chrome.tabs.create({url: url});
 | 
| -}
 | 
| -
 | 
| -function moreStories(event) {
 | 
| -  showUrl(moreStoriesUrl);
 | 
| -}
 | 
| -
 | 
| -function keyHandlerShowDesc(event) {
 | 
| -// Display content under heading when spacebar or right-arrow pressed
 | 
| -// Hide content when spacebar pressed again or left-arrow pressed
 | 
| -// Move to next heading when down-arrow pressed
 | 
| -// Move to previous heading when up-arrow pressed
 | 
| -  if (event.keyCode == 32) {
 | 
| -    showDesc(event);
 | 
| -  } else if ((this.parentNode.className == "item opened") &&
 | 
| -           (event.keyCode == 37)) {
 | 
| -    showDesc(event);
 | 
| -  } else if ((this.parentNode.className == "item") && (event.keyCode == 39)) {
 | 
| -    showDesc(event);
 | 
| -  } else if (event.keyCode == 40) {
 | 
| -    if (this.parentNode.nextSibling) {
 | 
| -      this.parentNode.nextSibling.children[1].focus();
 | 
| -    }
 | 
| -  } else if (event.keyCode == 38) {
 | 
| -    if (this.parentNode.previousSibling) {
 | 
| -      this.parentNode.previousSibling.children[1].focus();
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -function showDesc(event) {
 | 
| -  var item = event.currentTarget.parentNode;
 | 
| -  var items = document.getElementsByClassName("item");
 | 
| -  for (var i = 0; i < items.length; i++) {
 | 
| -    var iframe = items[i].getElementsByClassName("item_desc")[0];
 | 
| -    if (items[i] == item && items[i].className == "item") {
 | 
| -      items[i].className = "item opened";
 | 
| -      iframe.contentWindow.postMessage("reportHeight", "*");
 | 
| -      // Set the ARIA state indicating the tree item is currently expanded.
 | 
| -      items[i].getElementsByClassName("item_title")[0].
 | 
| -        setAttribute("aria-expanded", "true");
 | 
| -      iframe.tabIndex = 0;
 | 
| -    } else {
 | 
| -      items[i].className = "item";
 | 
| -      iframe.style.height = "0px";
 | 
| -      // Set the ARIA state indicating the tree item is currently collapsed.
 | 
| -      items[i].getElementsByClassName("item_title")[0].
 | 
| -        setAttribute("aria-expanded", "false");
 | 
| -      iframe.tabIndex = -1;
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -function iframeMessageHandler(e) {
 | 
| -  // Only listen to messages from one of our own iframes.
 | 
| -  var iframes = document.getElementsByTagName("IFRAME");
 | 
| -  for (var i = 0; i < iframes.length; i++) {
 | 
| -    if (iframes[i].contentWindow == e.source) {
 | 
| -      var msg = JSON.parse(e.data);
 | 
| -      if (msg) {
 | 
| -        if (msg.type == "size") {
 | 
| -          iframes[i].style.height = msg.size + "px";
 | 
| -        } else if (msg.type == "show") {
 | 
| -          var url = msg.url;
 | 
| -          if (url.indexOf("http://news.google.com") == 0) {
 | 
| -            // If the URL is a redirect URL, strip of the destination and go to
 | 
| -            // that directly.  This is necessary because the Google news
 | 
| -            // redirector blocks use of the redirects in this case.
 | 
| -            var index = url.indexOf("&url=");
 | 
| -            if (index >= 0) {
 | 
| -              url = url.substring(index + 5);
 | 
| -              index = url.indexOf("&");
 | 
| -              if (index >= 0)
 | 
| -                url = url.substring(0, index);
 | 
| -            }
 | 
| -          }
 | 
| -          showUrl(url);
 | 
| -        }
 | 
| -      }
 | 
| -      return;
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -window.addEventListener("message", iframeMessageHandler);
 | 
| -</script>
 | 
| -</head>
 | 
| -<body onload="main();">
 | 
| -<a id="title_a" tabIndex="0"><img id='title' alt="Google News logo"></a>
 | 
| -<div id="feed"></div>
 | 
| -</body>
 | 
| +  <head>
 | 
| +    <link href="feed.css" rel="stylesheet" type="text/css">
 | 
| +    <script src="feed.js"></script>
 | 
| +  </head>
 | 
| +  <body>
 | 
| +    <a id="title_a" tabIndex="0"><img id='title' alt="Google News logo"></a>
 | 
| +    <div id="feed"></div>
 | 
| +  </body>
 | 
|  </html>
 | 
|  
 | 
| 
 |