You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by mh...@apache.org on 2011/09/19 07:09:10 UTC

[Lucene.Net] svn commit: r1172426 [9/9] - in /incubator/lucene.net/branches/Lucene.Net_4e: build/scripts/ packages/SHFB/ packages/SHFB/Colorizer/ packages/SHFB/SharedContent/ packages/SHFB/Templates/ packages/SHFB/Web/

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/LoadIndexKeywords.aspx
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/LoadIndexKeywords.aspx?rev=1172426&view=auto
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/LoadIndexKeywords.aspx (added)
+++ incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/LoadIndexKeywords.aspx Mon Sep 19 05:09:06 2011
@@ -0,0 +1,102 @@
+<%@ Page Language="C#" EnableViewState="False" %>
+
+<script runat="server">
+//=============================================================================
+// System  : Sandcastle Help File Builder
+// File    : LoadIndexKeywords.aspx
+// Author  : Eric Woodruff  (Eric@EWoodruff.us) from code by Ferdinand Prantl
+// Updated : 04/01/2008
+// Note    : Copyright 2008, Eric Woodruff, All rights reserved
+// Compiler: Microsoft C#
+//
+// This file contains the code used to search for keywords within the help
+// topics using the full-text index files created by the help file builder.
+//
+// This code is published under the Microsoft Public License (Ms-PL).  A copy
+// of the license should be distributed with the code.  It can also be found
+// at the project website: http://SHFB.CodePlex.com.   This notice, the
+// author's name, and all copyright notices must remain intact in all
+// applications, documentation, and source files.
+//
+// Version     Date     Who  Comments
+// ============================================================================
+// 1.6.0.7  04/01/2008  EFW  Created the code
+//=============================================================================
+
+/// <summary>
+/// Render the keyword index
+/// </summary>
+/// <param name="writer">The writer to which the results are written</param>
+protected override void Render(HtmlTextWriter writer)
+{
+    XmlDocument ki;
+    XmlNode root, node;
+    StringBuilder sb = new StringBuilder(10240);
+    int startIndex = 0, endIndex;
+    string url, target;
+
+    ki = new XmlDocument();
+    ki.Load(Server.MapPath("WebKI.xml"));
+    root = ki.SelectSingleNode("HelpKI");
+
+    if(Request.QueryString["StartIndex"] != null)
+        startIndex = Convert.ToInt32(Request.QueryString["StartIndex"]) * 128;
+
+    endIndex = startIndex + 128;
+
+    if(endIndex > root.ChildNodes.Count)
+        endIndex = root.ChildNodes.Count;
+
+    if(startIndex > 0)
+    {
+        sb.Append("<div class=\"IndexItem\">\r\n" +
+            "<span>&nbsp;</span><a class=\"UnselectedNode\" " +
+            "onclick=\"javascript: return ChangeIndexPage(-1);\" " +
+            "href=\"#\"><b><< Previous page</b></a>\r\n</div>\r\n");
+    }
+
+    while(startIndex < endIndex)
+    {
+        node = root.ChildNodes[startIndex];
+
+        if(node.Attributes["Url"] == null)
+        {
+            url = "#";
+            target = String.Empty;
+        }
+        else
+        {
+            url = node.Attributes["Url"].Value;
+            target = " target=\"TopicContent\"";
+        }
+
+        sb.AppendFormat("<div class=\"IndexItem\">\r\n" +
+            "<span>&nbsp;</span><a class=\"UnselectedNode\" " +
+            "onclick=\"javascript: return SelectIndexNode(this);\" " +
+            "href=\"{0}\"{1}>{2}</a>\r\n", url, target,
+            HttpUtility.HtmlEncode(node.Attributes["Title"].Value));
+
+        if(node.ChildNodes.Count != 0)
+            foreach(XmlNode subNode in node.ChildNodes)
+                sb.AppendFormat("<div class=\"IndexSubItem\">\r\n" +
+                    "<img src=\"Item.gif\"/><a class=\"UnselectedNode\" " +
+                    "onclick=\"javascript: return SelectIndexNode(this);\" " +
+                    "href=\"{0}\" target=\"TopicContent\">{1}</a>\r\n</div>\r\n",
+                    subNode.Attributes["Url"].Value,
+                    HttpUtility.HtmlEncode(subNode.Attributes["Title"].Value));
+
+        sb.Append("</div>\r\n");
+
+        startIndex++;
+    }
+
+    if(startIndex < root.ChildNodes.Count)
+        sb.Append("<div class=\"IndexItem\">\r\n" +
+            "<span>&nbsp;</span><a class=\"UnselectedNode\" " +
+            "onclick=\"javascript: return ChangeIndexPage(1);\" " +
+            "href=\"#\"><b>Next page >></b></a>\r\n</div>\r\n");
+
+    writer.Write(sb.ToString());
+}
+
+</script>

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Search.gif
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Search.gif?rev=1172426&view=auto
==============================================================================
Files incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Search.gif (added) and incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Search.gif Mon Sep 19 05:09:06 2011 differ

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SearchHelp.aspx
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SearchHelp.aspx?rev=1172426&view=auto
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SearchHelp.aspx (added)
+++ incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SearchHelp.aspx Mon Sep 19 05:09:06 2011
@@ -0,0 +1,242 @@
+<%@ Page Language="C#" EnableViewState="False" %>
+
+<script runat="server">
+//=============================================================================
+// System  : Sandcastle Help File Builder
+// File    : SearchHelp.aspx
+// Author  : Eric Woodruff  (Eric@EWoodruff.us)
+// Updated : 07/03/2007
+// Note    : Copyright 2007, Eric Woodruff, All rights reserved
+// Compiler: Microsoft C#
+//
+// This file contains the code used to search for keywords within the help
+// topics using the full-text index files created by the help file builder.
+//
+// This code is published under the Microsoft Public License (Ms-PL).  A copy
+// of the license should be distributed with the code.  It can also be found
+// at the project website: http://SHFB.CodePlex.com.   This notice, the
+// author's name, and all copyright notices must remain intact in all
+// applications, documentation, and source files.
+//
+// Version     Date     Who  Comments
+// ============================================================================
+// 1.5.0.0  06/24/2007  EFW  Created the code
+//=============================================================================
+
+private class Ranking
+{
+    public string Filename, PageTitle;
+    public int Rank;
+    
+    public Ranking(string file, string title, int rank)
+    {
+        Filename = file;
+        PageTitle = title;
+        Rank = rank;
+    }
+}    
+
+/// <summary>
+/// Render the search results
+/// </summary>
+/// <param name="writer">The writer to which the results are written</param>
+protected override void Render(HtmlTextWriter writer)
+{
+    FileStream fs = null;
+    BinaryFormatter bf;
+    string searchText, ftiFile;
+    char letter;
+    bool sortByTitle = false;
+
+    // The keywords for which to search should be passed in the query string
+    searchText = this.Request.QueryString["Keywords"];
+
+    if(String.IsNullOrEmpty(searchText))
+    {
+        writer.Write("<b class=\"PaddedText\">Nothing found</b>");
+        return;
+    }
+
+    // An optional SortByTitle option can also be specified
+    if(this.Request.QueryString["SortByTitle"] != null)
+        sortByTitle = Convert.ToBoolean(this.Request.QueryString["SortByTitle"]);
+
+    List<string> keywords = this.ParseKeywords(searchText);
+    List<char> letters = new List<char>();
+    List<string> fileList;
+    Dictionary<string, List<long>> ftiWords, wordDictionary =
+        new Dictionary<string,List<long>>();
+
+    try
+    {
+        // Load the file index
+        fs = new FileStream(Server.MapPath("fti/FTI_Files.bin"), FileMode.Open,
+            FileAccess.Read);
+        bf = new BinaryFormatter();
+        fileList = (List<string>)bf.Deserialize(fs);
+        fs.Close();
+
+        // Load the required word index files
+        foreach(string word in keywords)
+        {
+            letter = word[0];
+            
+            if(!letters.Contains(letter))
+            {
+                letters.Add(letter);
+                ftiFile = Server.MapPath(String.Format(
+                    CultureInfo.InvariantCulture, "fti/FTI_{0}.bin", (int)letter));
+
+                if(File.Exists(ftiFile))
+                {
+                    fs = new FileStream(ftiFile, FileMode.Open, FileAccess.Read);
+                    ftiWords = (Dictionary<string, List<long>>)bf.Deserialize(fs);
+                    fs.Close();
+
+                    foreach(string ftiWord in ftiWords.Keys)
+                        wordDictionary.Add(ftiWord, ftiWords[ftiWord]);
+                }
+            }
+        }
+    }
+    finally
+    {
+        if(fs != null && fs.CanRead)
+            fs.Close();
+    }
+
+    // Perform the search and return the results as a block of HTML
+    writer.Write(this.Search(keywords, fileList, wordDictionary, sortByTitle));
+}
+
+/// <summary>
+/// Split the search text up into keywords
+/// </summary>
+/// <param name="keywords">The keywords to parse</param>
+/// <returns>A list containing the words for which to search</returns>
+private List<string> ParseKeywords(string keywords)
+{
+    List<string> keywordList = new List<string>();
+    string checkWord;
+    string[] words = Regex.Split(keywords, @"\W+");
+
+    foreach(string word in words)
+    {
+        checkWord = word.ToLower(CultureInfo.InvariantCulture);
+        
+        if(checkWord.Length > 2 && !Char.IsDigit(checkWord[0]) &&
+          !keywordList.Contains(checkWord))
+            keywordList.Add(checkWord);
+    }
+
+    return keywordList;
+}
+
+/// <summary>
+/// Search for the specified keywords and return the results as a block of
+/// HTML.
+/// </summary>
+/// <param name="keywords">The keywords for which to search</param>
+/// <param name="fileInfo">The file list</param>
+/// <param name="wordDictionary">The dictionary used to find the words</param>
+/// <param name="sortByTitle">True to sort by title, false to sort by
+/// ranking</param>
+/// <returns>A block of HTML representing the search results.</returns>
+private string Search(List<string> keywords, List<string> fileInfo,
+    Dictionary<string, List<long>> wordDictionary, bool sortByTitle)
+{
+    StringBuilder sb = new StringBuilder(10240);
+    Dictionary<string, List<long>> matches = new Dictionary<string, List<long>>();
+    List<long> occurrences;
+    List<int> matchingFileIndices = new List<int>(),
+        occurrenceIndices = new List<int>();
+    List<Ranking> rankings = new List<Ranking>();
+
+    string filename, title;
+    string[] fileIndex;
+    bool isFirst = true;
+    int idx, wordCount, matchCount;
+
+// TODO: Support boolean operators (AND, OR and maybe NOT)
+        
+    foreach(string word in keywords)
+    {
+        if(!wordDictionary.TryGetValue(word, out occurrences))
+            return "<b class=\"PaddedText\">Nothing found</b>";
+
+        matches.Add(word, occurrences);
+        occurrenceIndices.Clear();
+
+        // Get a list of the file indices for this match
+        foreach(long entry in occurrences)
+            occurrenceIndices.Add((int)(entry >> 16));
+            
+        if(isFirst)
+        {
+            isFirst = false;
+            matchingFileIndices.AddRange(occurrenceIndices);
+        }
+        else
+        {
+            // After the first match, remove files that do not appear for
+            // all found keywords.
+            for(idx = 0; idx < matchingFileIndices.Count; idx++)
+                if(!occurrenceIndices.Contains(matchingFileIndices[idx]))
+                {
+                    matchingFileIndices.RemoveAt(idx);
+                    idx--;
+                }
+        }
+    }
+
+    if(matchingFileIndices.Count == 0)
+        return "<b class=\"PaddedText\">Nothing found</b>";
+
+    // Rank the files based on the number of times the words occurs
+    foreach(int index in matchingFileIndices)
+    {
+        // Split out the title, filename, and word count
+        fileIndex = fileInfo[index].Split('\x0');
+
+        title = fileIndex[0];
+        filename = fileIndex[1];
+        wordCount = Convert.ToInt32(fileIndex[2]);
+        matchCount = 0;
+        
+        foreach(string word in keywords)
+        {
+            occurrences = matches[word];
+
+            foreach(long entry in occurrences)
+                if((int)(entry >> 16) == index)
+                    matchCount += (int)(entry & 0xFFFF);
+        }
+
+        rankings.Add(new Ranking(filename, title, matchCount * 1000 / wordCount));
+    }
+
+    // Sort by rank in descending order or by page title in ascending order
+    rankings.Sort(
+        delegate(Ranking x, Ranking y)
+        {
+            if(!sortByTitle)
+                return y.Rank - x.Rank;
+
+            return x.PageTitle.CompareTo(y.PageTitle);
+        });
+
+    // Format the file list and return the results
+    foreach(Ranking r in rankings)
+        sb.AppendFormat("<div class=\"TreeItem\">\r\n<img src=\"Item.gif\"/>" +
+            "<a class=\"UnselectedNode\" target=\"TopicContent\" " +
+            "href=\"{0}\" onclick=\"javascript: SelectSearchNode(this);\">" +
+            "{1}</a>\r\n</div>\r\n", r.Filename, r.PageTitle);
+
+    // Return the keywords used as well in a hidden span
+    sb.AppendFormat("<span id=\"SearchKeywords\" style=\"display: none\">{0}</span>",
+        String.Join(" ", keywords.ToArray()));
+
+    return sb.ToString();
+}
+
+</script>

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Splitter.gif
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Splitter.gif?rev=1172426&view=auto
==============================================================================
Files incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Splitter.gif (added) and incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Splitter.gif Mon Sep 19 05:09:06 2011 differ

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SyncTOC.gif
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SyncTOC.gif?rev=1172426&view=auto
==============================================================================
Files incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SyncTOC.gif (added) and incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/SyncTOC.gif Mon Sep 19 05:09:06 2011 differ

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.css
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.css?rev=1172426&view=auto
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.css (added)
+++ incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.css Mon Sep 19 05:09:06 2011
@@ -0,0 +1,163 @@
+/* File    : TOC.css
+// Author  : Eric Woodruff  (Eric@EWoodruff.us)
+// Updated : 09/07/2007
+//
+// Stylesheet for the table of content
+*/
+
+*
+{
+	margin: 0px 0px 0px 0px;
+	padding: 0px 0px 0px 0px;
+}
+
+body
+{
+    font-family: verdana, arial, sans-serif;
+    font-size: 8.5pt;
+    background-color: #6699CC;
+    color: White;
+	overflow: hidden;
+}
+
+input
+{
+	font-size: 8.5pt;
+}
+
+img
+{
+    border: 0;
+    margin-left: 5px;
+    margin-right: 2px;
+}
+
+img.TreeNodeImg
+{
+    cursor: pointer;
+}
+
+img.TOCLink
+{
+    cursor: pointer;
+    margin-left: 0;
+    margin-right: 0;
+}
+
+a.SelectedNode, a.UnselectedNode
+{
+	color: black;
+    text-decoration: none;
+	padding: 1px 3px 1px 3px;
+    white-space: nowrap;
+}
+
+a.SelectedNode
+{
+	background-color: #ffffff;
+    border: solid 1px #999999;
+	padding: 0px 2px 0px 2px;
+}
+
+a.UnselectedNode:hover, a.SelectedNode:hover
+{
+    background-color: #cccccc;
+    border: solid 1px #999999;
+	padding: 0px 2px 0px 2px;
+}
+
+.Visible
+{
+    display: block;
+    margin-left: 2em;
+}
+
+.Hidden
+{
+    display: none;
+}
+
+.Tree
+{
+	background-color: #f0f0f0;
+	color: Black;
+    width: 300px;
+	overflow: auto;
+}
+
+.TreeNode, .TreeItem
+{
+    white-space: nowrap;
+    margin: 2px 2px 2px 2px;
+}
+
+.TOCDiv
+{
+	position: relative;
+	float: left;
+	width: 300px;
+    height: 100%;
+}
+
+.TOCSizer
+{
+	clear: none;
+	float: left;
+	width: 10px;
+    height: 100%;
+    background-color: #6699CC;
+    background-image: url("Splitter.gif");
+    background-position:center center;
+	background-repeat:no-repeat;
+	position: relative;
+	cursor: w-resize;
+}
+
+.TopicContent
+{
+	position: relative;
+	float: right;
+    background-color: white;
+    height: 100%;
+}
+
+.SearchOpts
+{
+    padding: 5px 5px 0px 5px;
+    background-color: lightgrey;
+    color: black;
+    width: 300px;
+}
+
+.NavOpts
+{
+    padding: 5px 5px 0px 5px;
+    background-color: lightgrey;
+    color: black;
+    width: 300px;
+}
+
+.IndexOpts
+{
+    padding: 5px 5px 0px 5px;
+    background-color: lightgrey;
+    color: black;
+    width: 300px;
+}
+
+.IndexItem
+{
+    white-space: nowrap;
+    margin: 2px 2px 2px 2px;
+}
+
+.IndexSubItem
+{
+    white-space: nowrap;
+    margin: 2px 2px 2px 12px;
+}
+
+.PaddedText
+{
+    margin: 10px 10px 10px 10px;
+}

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.js
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.js?rev=1172426&view=auto
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.js (added)
+++ incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/TOC.js Mon Sep 19 05:09:06 2011
@@ -0,0 +1,743 @@
+//=============================================================================
+// System  : Sandcastle Help File Builder
+// File    : TOC.js
+// Author  : Eric Woodruff  (Eric@EWoodruff.us)
+// Updated : 01/03/2011
+// Note    : Copyright 2006-2011, Eric Woodruff, All rights reserved
+// Compiler: JavaScript
+//
+// This file contains the methods necessary to implement a simple tree view
+// for the table of content with a resizable splitter and Ajax support to
+// load tree nodes on demand.  It also contains the script necessary to do
+// full-text searches.
+//
+// This code is published under the Microsoft Public License (Ms-PL).  A copy
+// of the license should be distributed with the code.  It can also be found
+// at the project website: http://SHFB.CodePlex.com.   This notice, the
+// author's name, and all copyright notices must remain intact in all
+// applications, documentation, and source files.
+//
+// Version     Date     Who  Comments
+// ============================================================================
+// 1.3.0.0  09/12/2006  EFW  Created the code
+// 1.4.0.2  06/15/2007  EFW  Reworked to get rid of frame set and to add
+//                           support for Ajax to load tree nodes on demand.
+// 1.5.0.0  06/24/2007  EFW  Added full-text search capabilities
+// 1.6.0.7  04/01/2008  EFW  Merged changes from Ferdinand Prantl to add a
+//                           website keyword index.  Added support for "topic"
+//                           query string option.
+//=============================================================================
+
+// IE flag
+var isIE = (navigator.userAgent.indexOf("MSIE") >= 0);
+var isChrome = (navigator.userAgent.indexOf("Chrome") >= 0);
+
+// Minimum width of the TOC div
+var minWidth = 100;
+
+// Elements and sizing info
+var divTOC, divSizer, topicContent, divNavOpts, divSearchOpts, divSearchResults,
+    divIndexOpts, divIndexResults, divTree, docBody, maxWidth, offset,
+    txtSearchText, chkSortByTitle;
+
+// Last node selected
+var lastNode, lastSearchNode, lastIndexNode;
+
+// Last page with keyword index
+var currentIndexPage = 0;
+
+//============================================================================
+
+// Initialize the tree view and resize the content
+function Initialize()
+{
+    docBody = document.getElementsByTagName("body")[0];
+    divTOC = document.getElementById("TOCDiv");
+    divSizer = document.getElementById("TOCSizer");
+    topicContent = document.getElementById("TopicContent");
+    divNavOpts = document.getElementById("divNavOpts");
+    divSearchOpts = document.getElementById("divSearchOpts");
+    divSearchResults = document.getElementById("divSearchResults");
+    divIndexOpts = document.getElementById("divIndexOpts");
+    divIndexResults = document.getElementById("divIndexResults");
+    divTree = document.getElementById("divTree");
+    txtSearchText = document.getElementById("txtSearchText");
+    chkSortByTitle = document.getElementById("chkSortByTitle");
+
+    // The sizes are bit off in FireFox
+    if(!isIE)
+        divNavOpts.style.width = divSearchOpts.style.width =
+            divIndexOpts.style.width = 292;
+
+    ResizeTree();
+    SyncTOC();
+
+    // Use an alternate default page if a topic is specified in
+    // the query string.
+    var queryString = document.location.search;
+
+    if(queryString != "")
+    {
+        var idx, options = queryString.split(/[\?\=\&]/);
+
+        for(idx = 0; idx < options.length; idx++)
+            if(options[idx] == "topic" && idx + 1 < options.length)
+            {
+                topicContent.src = options[idx + 1];
+                break;
+            }
+    }
+}
+
+//============================================================================
+// Navigation and expand/collaps code
+
+// Synchronize the table of content with the selected page if possible
+function SyncTOC()
+{
+    var idx, anchor, base, href, url, anchors, treeNode, saveNode;
+
+    base = window.location.href;
+    base = base.substr(0, base.lastIndexOf("/") + 1);
+
+    if(base.substr(0, 5) == "file:" && base.substr(0, 8) != "file:///")
+        base = base.replace("file://", "file:///");
+
+    url = GetCurrentUrl();
+    if(url == "")
+        return false;
+
+    if(url.substr(0, 5) == "file:" && url.substr(0, 8) != "file:///")
+        url = url.replace("file://", "file:///");
+
+    while(true)
+    {
+        anchors = divTree.getElementsByTagName("A");
+        anchor = null;
+
+        for(idx = 0; idx < anchors.length; idx++)
+        {
+            href = anchors[idx].href;
+
+            if(href.substring(0, 7) != 'http://' &&
+              href.substring(0, 8) != 'https://' &&
+              href.substring(0, 7) != 'file://')
+                href = base + href;
+
+            if(href == url)
+            {
+                anchor = anchors[idx];
+                break;
+            }
+        }
+
+        if(anchor == null)
+        {
+            // If it contains a "#", strip anything after that and try again
+            if(url.indexOf("#") != -1)
+            {
+                url = url.substr(0, url.indexOf("#"));
+                continue;
+            }
+
+            return;
+        }
+
+        break;
+    }
+
+    // If found, select it and find the parent tree node
+    SelectNode(anchor);
+    saveNode = anchor;
+    lastNode = null;
+
+    while(anchor != null)
+    {
+        if(anchor.className == "TreeNode")
+        {
+            treeNode = anchor;
+            break;
+        }
+
+        anchor = anchor.parentNode;
+    }
+
+    // Expand it and all of its parents
+    while(anchor != null)
+    {
+        Expand(anchor);
+
+        anchor = anchor.parentNode;
+
+        while(anchor != null)
+        {
+            if(anchor.className == "TreeNode")
+                break;
+
+            anchor = anchor.parentNode;
+        }
+    }
+
+    lastNode = saveNode;
+
+    // Scroll the node into view
+    var windowTop = lastNode.offsetTop - divTree.offsetTop - divTree.scrollTop;
+    var windowBottom = divTree.clientHeight - windowTop - lastNode.offsetHeight;
+
+    if(windowTop < 0)
+        divTree.scrollTop += windowTop - 30;
+    else
+        if(windowBottom < 0)
+            divTree.scrollTop -= windowBottom - 30;
+}
+
+// Get the currently loaded URL from the IFRAME
+function GetCurrentUrl()
+{
+    var base, url = "";
+
+    try
+    {
+        url = window.frames["TopicContent"].document.URL.replace(/\\/g, "/");
+    }
+    catch(e)
+    {
+        // If this happens the user probably navigated to another frameset
+        // that didn't make itself the topmost frameset and we don't have
+        // control of the other frame anymore.  In that case, just reload
+        // our index page.
+        base = window.location.href;
+        base = base.substr(0, base.lastIndexOf("/") + 1);
+
+        // Chrome is too secure and won't let you access frame URLs when
+        // running from the file system unless you run Chrome with the
+        // "--disable-web-security" command line option.
+        if(isChrome && base.substr(0, 5) == "file:")
+        {
+            alert("Chrome security prevents access to file-based frame " +
+                "URLs.  As such, the TOC will not work with Index.html.  " +
+                "Either run this website on a web server, run Chrome with " +
+                "the '--disable-web-security' command line option, or use " +
+                "FireFox or Internet Explorer.");
+
+            return "";
+        }
+
+        if(base.substr(0, 5) == "file:" && base.substr(0, 8) != "file:///")
+            base = base.replace("file://", "file:///");
+
+        if(base.substr(0, 5) == "file:")
+            top.location.href = base + "Index.html";
+        else
+            top.location.href = base + "Index.aspx";
+    }
+
+    return url;
+}
+
+// Expand or collapse all nodes
+function ExpandOrCollapseAll(expandNodes)
+{
+    var divIdx, childIdx, img, divs = document.getElementsByTagName("DIV");
+    var childNodes, child, div, link, img;
+
+    for(divIdx = 0; divIdx < divs.length; divIdx++)
+        if(divs[divIdx].className == "Hidden" ||
+          divs[divIdx].className == "Visible")
+        {
+            childNodes = divs[divIdx].parentNode.childNodes;
+
+            for(childIdx = 0; childIdx < childNodes.length; childIdx++)
+            {
+                child = childNodes[childIdx];
+
+                if(child.className == "TreeNodeImg")
+                    img = child;
+
+                if(child.className == "Hidden" || child.className == "Visible")
+                {
+                    div = child;
+                    break;
+                }
+            }
+
+            if(div.className == "Visible" && !expandNodes)
+            {
+                div.className = "Hidden";
+                img.src = "Collapsed.gif";
+            }
+            else
+                if(div.className == "Hidden" && expandNodes)
+                {
+                    div.className = "Visible";
+                    img.src = "Expanded.gif";
+
+                    if(div.innerHTML == "")
+                        FillNode(div, true)
+                }
+        }
+}
+
+// Toggle the state of the specified node
+function Toggle(node)
+{
+    var i, childNodes, child, div, link;
+
+    childNodes = node.parentNode.childNodes;
+
+    for(i = 0; i < childNodes.length; i++)
+    {
+        child = childNodes[i];
+
+        if(child.className == "Hidden" || child.className == "Visible")
+        {
+            div = child;
+            break;
+        }
+    }
+
+    if(div.className == "Visible")
+    {
+        div.className = "Hidden";
+        node.src = "Collapsed.gif";
+    }
+    else
+    {
+        div.className = "Visible";
+        node.src = "Expanded.gif";
+
+        if(div.innerHTML == "")
+            FillNode(div, false)
+    }
+}
+
+// Expand the selected node
+function Expand(node)
+{
+    var i, childNodes, child, div, img;
+
+    // If not valid, don't bother
+    if(GetCurrentUrl() == "")
+        return false;
+
+    if(node.tagName == "A")
+        childNodes = node.parentNode.childNodes;
+    else
+        childNodes = node.childNodes;
+
+    for(i = 0; i < childNodes.length; i++)
+    {
+        child = childNodes[i];
+
+        if(child.className == "TreeNodeImg")
+            img = child;
+
+        if(child.className == "Hidden" || child.className == "Visible")
+        {
+            div = child;
+            break;
+        }
+    }
+
+    if(lastNode != null)
+        lastNode.className = "UnselectedNode";
+
+    div.className = "Visible";
+    img.src = "Expanded.gif";
+
+    if(node.tagName == "A")
+    {
+        node.className = "SelectedNode";
+        lastNode = node;
+    }
+
+    if(div.innerHTML == "")
+        FillNode(div, false)
+
+    return true;
+}
+
+// Set the style of the specified node to "selected"
+function SelectNode(node)
+{
+    // If not valid, don't bother
+    if(GetCurrentUrl() == "")
+        return false;
+
+    if(lastNode != null)
+        lastNode.className = "UnselectedNode";
+
+    node.className = "SelectedNode";
+    lastNode = node;
+
+    return true;
+}
+
+//============================================================================
+// Ajax-related code used to fill the tree nodes on demand
+
+function GetXmlHttpRequest()
+{
+    var xmlHttp = null;
+
+    // If IE7, Mozilla, Safari, etc., use the native object.
+    // Otherwise, use the ActiveX control for IE5.x and IE6.
+    if(window.XMLHttpRequest)
+        xmlHttp = new XMLHttpRequest();
+    else
+        if(window.ActiveXObject)
+            xmlHttp = new ActiveXObject("MSXML2.XMLHTTP.3.0");
+
+    return xmlHttp;
+}
+
+// Perform an AJAX-style request for the contents of a node and put the
+// contents into the empty div.
+function FillNode(div, expandChildren)
+{
+    var xmlHttp = GetXmlHttpRequest(), now = new Date();
+
+    if(xmlHttp == null)
+    {
+        div.innerHTML = "<b>XML HTTP request not supported!</b>";
+        return;
+    }
+
+    div.innerHTML = "Loading...";
+
+    // Add a unique hash to ensure it doesn't use cached results
+    xmlHttp.open("GET", "FillNode.aspx?Id=" + div.id + "&hash=" +
+        now.getTime(), true);
+
+    xmlHttp.onreadystatechange = function()
+    {
+        if(xmlHttp.readyState == 4)
+        {
+            div.innerHTML = xmlHttp.responseText;
+
+            if(expandChildren)
+                ExpandOrCollapseAll(true);
+        }
+    }
+
+    xmlHttp.send(null)
+}
+
+//============================================================================
+// Resizing code
+
+// Resize the tree div so that it fills the document body
+function ResizeTree()
+{
+    var y, newHeight;
+
+    if(self.innerHeight)    // All but IE
+        y = self.innerHeight;
+    else    // IE - Strict
+        if(document.documentElement && document.documentElement.clientHeight)
+            y = document.documentElement.clientHeight;
+        else    // Everything else
+            if(document.body)
+                y = document.body.clientHeight;
+
+    newHeight = y - parseInt(divNavOpts.style.height, 10) - 6;
+
+    if(newHeight < 50)
+        newHeight = 50;
+
+    divTree.style.height = newHeight;
+
+    newHeight = y - parseInt(divSearchOpts.style.height, 10) - 6;
+
+    if(newHeight < 100)
+        newHeight = 100;
+
+    divSearchResults.style.height = newHeight;
+
+    newHeight = y - parseInt(divIndexOpts.style.height, 10) - 6;
+
+    if(newHeight < 25)
+        newHeight = 25;
+
+    divIndexResults.style.height = newHeight;
+
+    // Resize the content div
+    ResizeContent();
+}
+
+// Resize the content div
+function ResizeContent()
+{
+    if(isIE)
+        maxWidth = docBody.clientWidth - 1;
+    else
+        maxWidth = docBody.clientWidth - 4;
+
+    topicContent.style.width = maxWidth - (divSizer.offsetLeft +
+        divSizer.offsetWidth);
+    maxWidth -= minWidth;
+}
+
+// This is called to prepare for dragging the sizer div
+function OnMouseDown(event)
+{
+    var x;
+
+    // Make sure the splitter is at the top of the z-index
+    divSizer.style.zIndex = 5000;
+
+    // The content is in an IFRAME which steals mouse events so
+    // hide it while resizing.
+    topicContent.style.display = "none";
+
+    if(isIE)
+        x = window.event.clientX + document.documentElement.scrollLeft +
+            document.body.scrollLeft;
+    else
+        x = event.clientX + window.scrollX;
+
+    // Save starting offset
+    offset = parseInt(divSizer.style.left, 10);
+
+    if(isNaN(offset))
+        offset = 0;
+
+    offset -= x;
+
+    if(isIE)
+    {
+        document.attachEvent("onmousemove", OnMouseMove);
+        document.attachEvent("onmouseup", OnMouseUp);
+        window.event.cancelBubble = true;
+        window.event.returnValue = false;
+    }
+    else
+    {
+        document.addEventListener("mousemove", OnMouseMove, true);
+        document.addEventListener("mouseup", OnMouseUp, true);
+        event.preventDefault();
+    }
+}
+
+// Resize the TOC and content divs as the sizer is dragged
+function OnMouseMove(event)
+{
+    var x, pos;
+
+    // Get cursor position with respect to the page
+    if(isIE)
+        x = window.event.clientX + document.documentElement.scrollLeft +
+            document.body.scrollLeft;
+    else
+        x = event.clientX + window.scrollX;
+
+    left = offset + x;
+
+    // Adjusts the width of the TOC divs
+    pos = (event.clientX > maxWidth) ? maxWidth :
+        (event.clientX < minWidth) ? minWidth : event.clientX;
+
+    divTOC.style.width = divSearchResults.style.width =
+        divIndexResults.style.width = divTree.style.width = pos;
+
+    if(!isIE)
+        pos -= 8;
+
+    divNavOpts.style.width = divSearchOpts.style.width =
+        divIndexOpts.style.width = pos;
+
+    // Resize the content div to fit in the remaining space
+    ResizeContent();
+}
+
+// Finish the drag operation when the mouse button is released
+function OnMouseUp(event)
+{
+    if(isIE)
+    {
+        document.detachEvent("onmousemove", OnMouseMove);
+        document.detachEvent("onmouseup", OnMouseUp);
+    }
+    else
+    {
+        document.removeEventListener("mousemove", OnMouseMove, true);
+        document.removeEventListener("mouseup", OnMouseUp, true);
+    }
+
+    // Show the content div again
+    topicContent.style.display = "inline";
+}
+
+//============================================================================
+// Search code
+
+function ShowHideSearch(show)
+{
+    if(show)
+    {
+        divNavOpts.style.display = divTree.style.display = "none";
+        divSearchOpts.style.display = divSearchResults.style.display = "";
+    }
+    else
+    {
+        divSearchOpts.style.display = divSearchResults.style.display = "none";
+        divNavOpts.style.display = divTree.style.display = "";
+    }
+}
+
+// When enter is hit in the search text box, do the search
+function OnSearchTextKeyPress(evt)
+{
+    if(evt.keyCode == 13)
+    {
+        PerformSearch();
+        return false;
+    }
+
+    return true;
+}
+
+// Perform a keyword search
+function PerformSearch()
+{
+    var xmlHttp = GetXmlHttpRequest(), now = new Date();
+
+    if(xmlHttp == null)
+    {
+        divSearchResults.innerHTML = "<b>XML HTTP request not supported!</b>";
+        return;
+    }
+
+    divSearchResults.innerHTML = "<span class=\"PaddedText\">Searching...</span>";
+
+    // Add a unique hash to ensure it doesn't use cached results
+    xmlHttp.open("GET", "SearchHelp.aspx?Keywords=" + txtSearchText.value +
+        "&SortByTitle=" + (chkSortByTitle.checked ? "true" : "false") +
+        "&hash=" + now.getTime(), true);
+
+    xmlHttp.onreadystatechange = function()
+    {
+        if(xmlHttp.readyState == 4)
+        {
+            divSearchResults.innerHTML = xmlHttp.responseText;
+
+            lastSearchNode = divSearchResults.childNodes[0].childNodes[1];
+
+            while(lastSearchNode != null && lastSearchNode.tagName != "A")
+                lastSearchNode = lastSearchNode.nextSibling;
+
+            if(lastSearchNode != null)
+            {
+                SelectSearchNode(lastSearchNode);
+                topicContent.src = lastSearchNode.href;
+            }
+        }
+    }
+
+    xmlHttp.send(null)
+}
+
+// Set the style of the specified search result node to "selected"
+function SelectSearchNode(node)
+{
+    if(lastSearchNode != null)
+        lastSearchNode.className = "UnselectedNode";
+
+    node.className = "SelectedNode";
+    lastSearchNode = node;
+
+    return true;
+}
+
+//============================================================================
+// KeyWordIndex code
+
+function ShowHideIndex(show)
+{
+    if(show)
+    {
+        PopulateIndex(currentIndexPage);
+
+        divNavOpts.style.display = divTree.style.display = "none";
+        divIndexOpts.style.display = divIndexResults.style.display = "";
+    }
+    else
+    {
+        divIndexOpts.style.display = divIndexResults.style.display = "none";
+        divNavOpts.style.display = divTree.style.display = "";
+    }
+}
+
+// Populate keyword index
+function PopulateIndex(startIndex)
+{
+    var xmlHttp = GetXmlHttpRequest(), now = new Date();
+    var firstNode;
+
+    if(xmlHttp == null)
+    {
+        divIndexResults.innerHTML = "<b>XML HTTP request not supported!</b>";
+        return;
+    }
+
+    divIndexResults.innerHTML = "<span class=\"PaddedText\">Loading " +
+        "keyword index...</span>";
+
+    // Add a unique hash to ensure it doesn't use cached results
+    xmlHttp.open("GET", "LoadIndexKeywords.aspx?StartIndex=" + startIndex +
+      "&hash=" + now.getTime(), true);
+
+    xmlHttp.onreadystatechange = function()
+    {
+        if(xmlHttp.readyState == 4)
+        {
+            divIndexResults.innerHTML = xmlHttp.responseText;
+
+            if(startIndex > 0)
+            {
+                firstNode = divIndexResults.childNodes[1];
+
+                if(firstNode != null && !firstNode.innerHTML)
+                    firstNode = divIndexResults.childNodes[2];
+            }
+            else
+                firstNode = divIndexResults.childNodes[0];
+
+            if(firstNode != null)
+                lastIndexNode = firstNode.childNodes[0];
+
+            while(lastIndexNode != null && lastIndexNode.tagName != "A")
+                lastIndexNode = lastIndexNode.nextSibling;
+
+            if(lastIndexNode != null)
+            {
+                SelectIndexNode(lastIndexNode);
+                topicContent.src = lastIndexNode.href;
+            }
+
+            currentIndexPage = startIndex;
+        }
+    }
+
+    xmlHttp.send(null)
+}
+
+// Set the style of the specified keyword index node to "selected"
+function SelectIndexNode(node)
+{
+    if(lastIndexNode != null)
+        lastIndexNode.className = "UnselectedNode";
+
+    node.className = "SelectedNode";
+    lastIndexNode = node;
+
+    return true;
+}
+
+// Changes the current page with keyword index forward or backward
+function ChangeIndexPage(direction)
+{
+    PopulateIndex(currentIndexPage + direction);
+
+    return false;
+}

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Web.Config
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Web.Config?rev=1172426&view=auto
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Web.Config (added)
+++ incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/Web.Config Mon Sep 19 05:09:06 2011
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<configuration>
+  <system.web>
+    <compilation debug="false"/>
+    <pages>
+      <namespaces>
+        <add namespace="System"/>
+        <add namespace="System.Collections.Generic"/>
+        <add namespace="System.Globalization"/>
+        <add namespace="System.IO"/>
+        <add namespace="System.Runtime.Serialization.Formatters.Binary"/>
+        <add namespace="System.Text"/>
+        <add namespace="System.Text.RegularExpressions"/>
+        <add namespace="System.Web"/>
+        <add namespace="System.Web.UI"/>
+        <add namespace="System.Xml"/>
+        <add namespace="System.Xml.XPath"/>
+      </namespaces>
+    </pages>
+  </system.web>
+</configuration>

Added: incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/favicon.ico
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/favicon.ico?rev=1172426&view=auto
==============================================================================
Files incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/favicon.ico (added) and incubator/lucene.net/branches/Lucene.Net_4e/packages/SHFB/Web/favicon.ico Mon Sep 19 05:09:06 2011 differ