public static string GetHtml (string url, HelpSource helpSource, out Node match) { string htmlContent = null; match = null; if (helpSource != null) htmlContent = AppDelegate.Root.RenderUrl (url, generator, out match, helpSource); if (htmlContent == null) { // the displayed url have a lower case type code (e.g. t: instead of T:) which confuse monodoc if (url.Length > 2 && url[1] == ':') url = char.ToUpperInvariant (url[0]) + url.Substring (1); // It may also be url encoded so decode it url = Uri.UnescapeDataString (url); htmlContent = AppDelegate.Root.RenderUrl (url, generator, out match, helpSource); if (htmlContent != null && match != null && match.Tree != null) helpSource = match.Tree.HelpSource; } if (htmlContent == null) return null; var html = new StringWriter (); html.Write ("<html>\n<head><title>{0}</title>", url); if (helpSource != null) { if (HtmlGenerator.InlineCss != null) html.Write (" <style type=\"text/css\">{0}</style>\n", HtmlGenerator.InlineCss); /*if (helpSource.InlineJavaScript != null) html.Write ("<script type=\"text/JavaScript\">{0}</script>\n", helpSource.InlineJavaScript);*/ } html.Write ("</head><body>"); html.Write (htmlContent); html.Write ("</body></html>\n"); return html.ToString (); }
/// <summary> /// Load from file constructor /// </summary> public Tree (HelpSource hs, string filename) { HelpSource = hs; Encoding utf8 = new UTF8Encoding (false, true); if (!File.Exists (filename)){ throw new FileNotFoundException (); } InputStream = File.OpenRead (filename); InputReader = new BinaryReader (InputStream, utf8); byte [] sig = InputReader.ReadBytes (4); if (!GoodSig (sig)) throw new Exception ("Invalid file format"); InputStream.Position = 4; // Try to read version information if (InputReader.ReadInt32 () == -(int)'v') VersionNumber = InputReader.ReadInt64 (); else InputStream.Position -= 4; var position = InputReader.ReadInt32 (); rootNode = new Node (this, position); InflateNode (rootNode); }
public override string GetText (string url, out Node match_node) { match_node = null; string c = GetCachedText (url); if (c != null) return c; if (url.IndexOf (MAN_PREFIX) > -1) return GetTextFromUrl (url); if (url == "root:") { // display an index of sub-nodes. StringBuilder buf = new StringBuilder (); buf.Append ("<table bgcolor=\"#b0c4de\" width=\"100%\" cellpadding=\"5\"><tr><td><h3>Mono Documentation Library</h3></td></tr></table>"); buf.Append ("<p>Available man pages:</p>").Append ("<blockquote>"); foreach (Node n in Tree.Nodes) { buf.Append ("<a href=\"").Append (n.Element).Append ("\">") .Append (n.Caption).Append ("</a><br/>"); } buf.Append ("</blockquote>"); return buf.ToString (); } return null; }
public static string GetHtml (string url, HelpSource helpSource, out Node match) { string htmlContent = null; match = null; if (helpSource != null) htmlContent = helpSource.GetText (url, out match); if (htmlContent == null){ htmlContent = AppDelegate.Root.RenderUrl (url, out match); if (htmlContent != null && match != null && match.tree != null){ helpSource = match.tree.HelpSource; } } if (htmlContent == null) return null; var html = new StringWriter (); html.Write ("<html>\n<head><title>{0}</title>", url); if (helpSource != null){ if (helpSource.InlineCss != null) html.Write (" <style type=\"text/css\">{0}</style>\n", helpSource.InlineCss); if (helpSource.InlineJavaScript != null) html.Write ("<script type=\"text/JavaScript\">{0}</script>\n", helpSource.InlineJavaScript); } html.Write ("</head><body>"); html.Write (htmlContent); html.Write ("</body></html>\n"); return html.ToString (); }
public override string GetText (string url, out Node match_node) { string ret = null; match_node = null; if (url.StartsWith ("ecmaspec:")) { match_node = MatchNode (Tree, url); ret = GetTextFromUrl (url); } if (url == "root:") { if (use_css) ret = "<div id=\"ecmaspec\" class=\"header\"><div class=\"title\">C# Language Specification</div></div>"; else ret = "<table width=\"100%\" bgcolor=\"#b0c4de\" cellpadding=\"5\"><tr><td><h3>C# Language Specification</h3></tr></td></table>"; match_node = Tree; } if (ret != null && match_node != null && match_node.Nodes != null && match_node.Nodes.Count > 0) { ret += "<p>In This Section:</p><ul>\n"; foreach (Node child in match_node.Nodes) { ret += "<li><a href=\"" + child.URL + "\">" + child.Caption + "</a></li>\n"; } ret += "</ul>\n"; } if (ret != null) return BuildHtml (css_ecmaspec_code, ret); else return null; }
public override string GetText (string url, out Node match_node) { match_node = null; string c = GetCachedText (url); if (c != null) return c; if (url == "root:") { StringBuilder sb = new StringBuilder (); sb.Append ("<table width=\"100%\" bgcolor=\"#b0c4de\" cellpadding=\"5\"><tr><td><h3>Mono Handbook</h3></tr></td></table>"); foreach (Node n in Tree.Nodes) { if (n.IsLeaf) { sb.AppendFormat ("<a href='{0}'>{1}</a><br/>", n.Element.Replace ("source-id:NNN", "source-id:" + SourceID), n.Caption); } else { sb.AppendFormat ("<h2>{0}</h2>", n.Caption); foreach (Node subNode in n.Nodes) { sb.AppendFormat ("<a href='{0}'>{1}</a><br/>", subNode.Element.Replace ("source-id:NNN", "source-id:" + SourceID), subNode.Caption); } } } return sb.ToString (); } if (url.IndexOf (XHTML_PREFIX) > -1) return GetTextFromUrl (url); return null; }
void PopulateNode (XPathNodeIterator nodes, Node treeNode) { while (nodes.MoveNext ()) { XPathNavigator n = nodes.Current; string secNumber = n.GetAttribute ("number", ""), secName = n.GetAttribute ("name", ""); treeNode.tree.HelpSource.Message (TraceLevel.Info, "\tSection: " + secNumber); treeNode.tree.HelpSource.PackFile (Path.Combine (basedir, secNumber + ".xml"), secNumber); Node thisNode = treeNode.LookupNode (secNumber + ": " + secName, "ecmaspec:" + secNumber); if (n.HasChildren) PopulateNode (n.SelectChildren ("node", ""), thisNode); } }
internal static string GetImageKeyFromNode(Node node) { if (node.Caption.EndsWith (" Class")) return "class.png"; if (node.Caption.EndsWith (" Interface")) return "interface.png"; if (node.Caption.EndsWith (" Structure")) return "structure.png"; if (node.Caption.EndsWith (" Enumeration")) return "enumeration.png"; if (node.Caption.EndsWith (" Delegate")) return "delegate.png"; var url = node.PublicUrl; if (!string.IsNullOrEmpty (url) && url.StartsWith ("N:")) return "namespace.png"; return null; }
internal static string GetParentImageKeyFromNode(Node node) { switch (node.Caption) { case "Methods": case "Constructors": return "method.png"; case "Properties": return "property.png"; case "Events": return "event.png"; case "Members": return "members.png"; case "Fields": return "field.png"; } return null; }
/// <summary> /// Load from file constructor /// </summary> public Tree (HelpSource hs, string filename) #if LEGACY_MODE : base (null, null) #endif { HelpSource = hs; Encoding utf8 = new UTF8Encoding (false, true); if (!File.Exists (filename)){ throw new FileNotFoundException (); } InputStream = File.OpenRead (filename); InputReader = new BinaryReader (InputStream, utf8); byte [] sig = InputReader.ReadBytes (4); if (!GoodSig (sig)) throw new Exception ("Invalid file format"); InputStream.Position = 4; // Try to read old version information if (InputReader.ReadInt32 () == VersionNumberKey) VersionNumber = InputReader.ReadInt64 (); else { // We try to see if there is a version number at the end of the file InputStream.Seek (-(4 + 8), SeekOrigin.End); // VersionNumberKey + long try { if (InputReader.ReadInt32 () == VersionNumberKey) VersionNumber = InputReader.ReadInt64 (); } catch {} // We set the stream back at the beginning of the node definition list InputStream.Position = 4; } var position = InputReader.ReadInt32 (); #if !LEGACY_MODE rootNode = new Node (this, position); #else Address = position; #endif InflateNode (RootNode); }
public static string GetHtml (string url, HelpSource helpSource, out Node match) { Console.WriteLine ("Calling URL {0} with HelpSource {1}", url, helpSource == null ? "(null)" : helpSource.Name); string htmlContent = null; match = null; if (helpSource != null) htmlContent = helpSource.GetText (url, out match); if (htmlContent == null){ // the displayed url have a lower case type code (e.g. t: instead of T:) which confuse monodoc if (url.Length > 2 && url[1] == ':') url = char.ToUpperInvariant (url[0]) + url.Substring (1); // It may also be url encoded so decode it url = Uri.UnescapeDataString (url); htmlContent = Program.Root.RenderUrl (url, out match); if (htmlContent != null && match != null && match.tree != null){ helpSource = match.tree.HelpSource; } } if (htmlContent == null) return null; var html = new StringWriter (); html.Write ("<html>\n<head><title>{0}</title>", url); if (helpSource != null){ if (helpSource.InlineCss != null) html.Write (" <style type=\"text/css\">{0}</style>\n", helpSource.InlineCss); if (helpSource.InlineJavaScript != null) html.Write ("<script type=\"text/JavaScript\">{0}</script>\n", helpSource.InlineJavaScript); } html.Write ("</head><body>"); html.Write (htmlContent); html.Write ("</body></html>\n"); return html.ToString (); }
#pragma warning disable 219 void PopulateDir (Node me, string dir) { Console.WriteLine ("Adding: " + dir); foreach (string child_dir in Directory.GetDirectories (dir)){ string url = Path.GetFileName (child_dir); Node n = me.LookupNode ("Dir: " + url, "simple-directory:" + url); PopulateDir (me, child_dir); } foreach (string file in Directory.GetFiles (dir)){ Console.WriteLine (" File: " + file); string file_code = me.tree.HelpSource.PackFile (file); // // The url element encoded for the file is: // originalfilename#CODE // // The code is assigned to us after the file has been packaged // We use the original-filename later to render html or text files // Node n = me.LookupNode (Path.GetFileName (file), file + "#" + file_code); } }
public override string GetText (string url, out Node match_node) { if (url == "root:") { match_node = null; //load index.xml XmlDocument index = new XmlDocument (); index.Load (Path.Combine (basedir.FullName, "index.xml")); XmlNodeList nodes = index.SelectNodes ("/Overview/Types/Namespace"); //recreate masteroverview.xml XmlDocument summary = new XmlDocument (); XmlElement elements = summary.CreateElement ("elements"); foreach (XmlNode node in nodes) { XmlElement ns = summary.CreateElement ("namespace"); XmlAttribute attr = summary.CreateAttribute ("ns"); attr.Value = EcmaDoc.GetDisplayName (node); ns.Attributes.Append (attr); elements.AppendChild (ns); } summary.AppendChild (elements); XmlReader reader = new XmlTextReader (new StringReader (summary.OuterXml)); //transform the recently created masteroverview.xml XsltArgumentList args = new XsltArgumentList(); args.AddExtensionObject("monodoc:///extensions", ExtObject); args.AddParam("show", "", "masteroverview"); string s = Htmlize(reader, args); return BuildHtml (css_ecma_code, js_code, s); } return base.GetText(url, out match_node); }
// // Extract a large name for the Node // (copied from mono-tools/docbrowser/browser.Render() static string LargeName (Node matched_node) { string[] parts = matched_node.URL.Split('/', '#'); if(parts.Length == 3 && parts[2] != String.Empty) { //List of Members, properties, events, ... return parts[1] + ": " + matched_node.Caption; } else if(parts.Length >= 4) { //Showing a concrete Member, property, ... return parts[1] + "." + matched_node.Caption; } else { return matched_node.Caption; } }
internal void ShowNode (Node n) { if (n == null) return; if (!nodeToWrapper.ContainsKey (n)) ShowNode (n.Parent); // If the dictionary still doesn't contain anything about us, time to leave if (!nodeToWrapper.ContainsKey (n)) return; var item = nodeToWrapper [n]; outlineView.ExpandItem (item); // Focus the last child, then this child to ensure we show as much as possible if (n.Nodes.Count > 0) ScrollToVisible ((Node) n.Nodes [n.Nodes.Count-1]); var row = ScrollToVisible (n); ignoreSelect = true; outlineView.SelectRows (new NSIndexSet (row), false); ignoreSelect = false; }
// // This routine has to perform a lookup on a type. // // Example: T:System.Text.StringBuilder // // The prefix is the kind of opereation being requested (T:, E:, M: etc) // ns is the namespace being looked up // type is the type being requested // // This has to walk our toplevel (which is always a namespace) // And then the type space, and then walk further down depending on the request // public override string RenderTypeLookup (string prefix, string ns, string type, string member, out Node match_node) { string url = GetUrlForType (prefix, ns, type, member, out match_node); if (url == null) return null; return GetTextFromUrl (url); }
public override string GetText (string url, out Node match_node) { match_node = null; string cached = GetCachedText (url); if (cached != null) return cached; if (url == "root:") { XmlReader summary = GetHelpXml ("mastersummary.xml"); if (summary == null) return null; XsltArgumentList args = new XsltArgumentList(); args.AddExtensionObject("monodoc:///extensions", ExtObject); args.AddParam("show", "", "masteroverview"); string s = Htmlize(summary, args); return BuildHtml (css_ecma_code, js_code, s); } if (url.StartsWith ("ecma:")) { string s = GetTextFromUrl (url); return BuildHtml (css_ecma_code, js_code, s); } return null; }
void PopulateClass (Tree tree, string ns, Node ns_node, string file) { XmlDocument doc = new XmlDocument (); doc.Load (file); string name = EcmaDoc.GetClassName (doc); string assembly = EcmaDoc.GetClassAssembly (doc); string kind = EcmaDoc.GetTypeKind (doc); string full = EcmaDoc.GetFullClassName (doc); Node class_node; string file_code = ns_node.tree.HelpSource.PackFile (file); XmlNode class_summary = detached.ImportNode (doc.SelectSingleNode ("/Type/Docs/summary"), true); ArrayList l = (ArrayList) class_summaries [ns]; if (l == null){ l = new ArrayList (); class_summaries [ns] = (object) l; } l.Add (new TypeInfo (kind, assembly, full, name, class_summary)); class_node = ns_node.LookupNode (String.Format ("{0} {1}", name, kind), "ecma:" + file_code + "#" + name + "/"); if (kind == "Delegate") { if (doc.SelectSingleNode("/Type/ReturnValue") == null) tree.HelpSource.Message (TraceLevel.Error, "Delegate " + name + " does not have a ReturnValue node. See the ECMA-style updates."); } if (kind == "Enumeration") return; if (kind == "Delegate") return; // // Always add the Members node // class_node.CreateNode ("Members", "*"); PopulateMember (doc, name, class_node, "Constructor", "Constructors"); PopulateMember (doc, name, class_node, "Method", "Methods"); PopulateMember (doc, name, class_node, "Property", "Properties"); PopulateMember (doc, name, class_node, "Field", "Fields"); PopulateMember (doc, name, class_node, "Event", "Events"); PopulateMember (doc, name, class_node, "Operator", "Operators"); }
// // Performs an XPath query on the document to extract the nodes for the various members // we also use some extra text to pluralize the caption // void PopulateMember (XmlDocument doc, string typename, Node node, string type, string caption) { string select = type; if (select == "Operator") select = "Method"; XmlNodeList list1 = doc.SelectNodes (String.Format ("/Type/Members/Member[MemberType=\"{0}\"]", select)); ArrayList list = new ArrayList(); int i = 0; foreach (XmlElement n in list1) { n.SetAttribute("assembler_index", (i++).ToString()); if (type == "Method" && GetMemberName(n).StartsWith("op_")) continue; if (type == "Operator" && !GetMemberName(n).StartsWith("op_")) continue; list.Add(n); } int count = list.Count; if (count == 0) return; Node nodes_node; string key = type.Substring (0, 1); nodes_node = node.CreateNode (caption, key); switch (type) { case "Event": case "Field": foreach (XmlElement n in list) nodes_node.CreateNode (GetMemberName (n), n.GetAttribute("assembler_index")); break; case "Constructor": foreach (XmlElement n in list) nodes_node.CreateNode (EcmaHelpSource.MakeSignature(n, typename), n.GetAttribute("assembler_index")); break; case "Property": // properties with indexers can be overloaded too case "Method": case "Operator": foreach (XmlElement n in list) { bool multiple = false; foreach (XmlNode nn in list) { if (n != nn && GetMemberName(n) == nn.Attributes ["MemberName"].InnerText) { multiple = true; break; } } string group, name, sig; if (type != "Operator") { name = GetMemberName(n); sig = EcmaHelpSource.MakeSignature(n, null); group = name; } else { EcmaHelpSource.MakeOperatorSignature(n, out name, out sig); group = name; } if (multiple) { nodes_node.LookupNode (group, group) .CreateNode (sig, n.GetAttribute("assembler_index")); } else { nodes_node.CreateNode (name, n.GetAttribute("assembler_index")); } } foreach (Node n in nodes_node.Nodes) { if (!n.IsLeaf) n.Sort (); } break; default: throw new InvalidOperationException(); } nodes_node.Sort (); }
public Tree (HelpSource hs, Node parent, string caption, string element) : base (parent, caption, element) { HelpSource = hs; }
string RenderMemberLookup (string typename, string member, ref Node type_node) { if (type_node.Nodes == null) return null; string membername = member; string[] argtypes = null; if (member.IndexOf("(") > 0) { membername = membername.Substring(0, member.IndexOf("(")); member = member.Replace("@", "&"); // reform the member signature with CTS names string x = member.Substring(member.IndexOf("(")+1); argtypes = x.Substring(0, x.Length-1).Split(',', ':'); // operator signatures have colons if (membername == ".ctor") membername = typename; member = membername + "("; for (int i = 0; i < argtypes.Length; i++) { argtypes[i] = EcmaDoc.ConvertCTSName(argtypes[i]); if (i > 0) member += ","; member += argtypes[i]; } member += ")"; } // Check if a node caption matches exactly bool isoperator = false; if ((membername == "op_Implicit" || membername == "op_Explicit") && argtypes.Length == 2) { isoperator = true; membername = "Conversion"; member = argtypes[0] + " to " + argtypes[1]; } else if (membername.StartsWith("op_")) { isoperator = true; membername = membername.Substring(3); } foreach (Node x in type_node.Nodes){ if (x.Nodes == null) continue; if (isoperator && x.Caption != "Operators") continue; foreach (Node m in x.Nodes) { string caption = m.Caption; string ecaption = ToEscapedMemberName (caption); if (m.IsLeaf) { // No overloading (usually), is just the member name. The whole thing for constructors. if (caption == membername || caption == member || ecaption == membername || ecaption == member) { type_node = m; return GetTextFromUrl (m.URL); } } else if (caption == member || ecaption == member) { // Though there are overloads, no arguments are in the url, so use this base node type_node = m; return GetTextFromUrl (m.URL); } else { // Check subnodes which are the overloads -- must match signature foreach (Node mm in m.Nodes) { ecaption = ToEscapedTypeName (mm.Caption); if (mm.Caption == member || ecaption == member) { type_node = mm; return GetTextFromUrl (mm.URL); } } } } } return null; }
public string GetUrlForType (string prefix, string ns, string type, string member, out Node match_node) { if (!prefix.EndsWith(":")) throw new ArgumentException("prefix"); if (member != null) member = member.Replace ("#", ".").Replace ("{", "<").Replace ("}", ">"); // If a nested type, compare only inner type name to node list. // This should be removed when the node list doesn't lose the containing type name. type = ToEscapedTypeName (type.Replace("+", ".")); MatchAttempt[] attempts = GetAttempts (ns, type); foreach (Node ns_node in Tree.Nodes){ string ns_node_namespace = ns_node.Element.Substring (2); if (!MatchesNamespace (attempts, ns_node_namespace, out type)) continue; foreach (Node type_node in ns_node.Nodes){ string element = type_node.Element; string cname; if (element.StartsWith("T:")) { cname = element.Substring(2); string _ns; RootTree.GetNamespaceAndType (cname, out _ns, out cname); cname = ToEscapedTypeName (cname); int pidx = cname.LastIndexOf ("."); cname = cname.Substring(pidx+1); pidx = cname.LastIndexOf ("/"); if (pidx != -1) cname = cname.Substring(0, pidx); cname = cname.Replace("+", "."); } else { int pidx = element.IndexOf ("#"); int sidx = element.IndexOf ("/"); cname = element.Substring (pidx + 1, sidx-pidx-1); cname = ToEscapedTypeName (cname); } //Console.WriteLine ("t:{0} cn:{1} p:{2}", type, cname, prefix); if (type == cname && prefix == "T:") { match_node = type_node; return type_node.URL; } else if (type.StartsWith (cname)){ int p = cname.Length; match_node = type_node; if (type == cname){ string ret = RenderMemberLookup (type, member, ref match_node); if (ret == null) return type_node.URL; return match_node.URL; } else if (type [p] == '/'){ // // This handles summaries // match_node = null; foreach (Node nd in type_node.Nodes) { if (nd.Element [nd.Element.Length - 1] == type [p + 1]) { match_node = nd; break; } } string ret = type_node.URL; if (!ret.EndsWith("/")) ret += "/"; return ret + type.Substring (p + 1); } } } } match_node = null; return null; }
public virtual string GetIdFromUrl (string prefix, string ns, string type) { Node tmp_node = new Node (Tree, "", ""); string url = GetUrlForType (prefix, ns, type, null, out tmp_node); if (url == null) return null; return GetFile (url.Substring (5), out url); }
internal void LoadUrl (string url, bool syncTreeView = false, HelpSource source = null, bool addToHistory = true) { if (url.StartsWith ("#")) { Console.WriteLine ("FIXME: Anchor jump"); return; } // In case user click on an external link e.g. [Android documentation] link at bottom of MonoDroid docs if (url.StartsWith ("http://")) { UrlLauncher.Launch (url); return; } Console.WriteLine ("Loading {0}", url); var ts = Interlocked.Increment (ref loadUrlTimestamp); Task.Factory.StartNew (() => { Node node; var res = DocTools.GetHtml (url, source, out node); return new { Node = node, Html = res }; }).ContinueWith (t => { var node = t.Result.Node; var res = t.Result.Html; if (res != null){ BeginInvokeOnMainThread (() => { if (ts < loadUrlTimestamp) return; currentUrl = node == null ? url : node.PublicUrl; InvalidateRestorableState (); if (addToHistory) history.AppendHistory (new LinkPageVisit (this, currentUrl)); LoadHtml (res); this.match = node; if (syncTreeView) { // When navigation occurs after a link on search result is clicked // we need to show the panel so that ShowNode work as expected tabSelector.SelectAt (0); } // Bookmark spinner management var bookmarkIndex = AppDelegate.BookmarkManager.FindIndexOfBookmarkFromUrl (url); if (bookmarkIndex == -1 || bookmarkIndex < bookmarkSelector.ItemCount) bookmarkSelector.SelectItem (bookmarkIndex); }); } }); }
internal void LoadUrl (string url, bool syncTreeView = false, HelpSource source = null, bool addToHistory = true) { if (url.StartsWith ("#")) { Console.WriteLine ("FIXME: Anchor jump"); return; } var ts = Interlocked.Increment (ref loadUrlTimestamp); Task.Factory.StartNew (() => { Node node; var res = DocTools.GetHtml (url, source, out node); return new { Node = node, Html = res }; }).ContinueWith (t => { var node = t.Result.Node; var res = t.Result.Html; if (res != null){ BeginInvokeOnMainThread (() => { if (ts < loadUrlTimestamp) return; currentUrl = node == null ? url : node.PublicUrl; if (addToHistory) history.AppendHistory (new LinkPageVisit (this, currentUrl)); LoadHtml (res); if (syncTreeView) { // When navigation occurs after a link on search result is clicked // we need to show the panel so that ShowNode work as expected tabSelector.SelectAt (0); this.match = node; } // Bookmark spinner management if (currentBookmarkIndex != -1) { bookmarkSelector.SelectItem (currentBookmarkIndex); currentBookmarkIndex = -1; } else { bookmarkSelector.SelectItem (-1); } }); } }); }
public override string GetText (string url, out Node match_node) { match_node = null; if (url == "root:") if (HelpSource.use_css) return BuildHtml (css_error_code, "<div id=\"error_ref\" class=\"header\"><div class=\"title\">Compiler Error Reference</div></div>"); else return BuildHtml (String.Empty, "<table width=\"100%\" bgcolor=\"#b0c4de\" cellpadding=\"5\"><tr><td><h3>Compiler Error Reference</h3></tr></td></table>"); if (!url.StartsWith ("error:")) return null; foreach (Node n in Tree.Nodes) { if (n.Element != url) continue; match_node = n; XmlSerializer reader = new XmlSerializer (typeof (ErrorDocumentation)); ErrorDocumentation d = (ErrorDocumentation)reader.Deserialize ( GetHelpStream (n.Element.Substring (6)) ); return BuildHtml (css_error_code, d.RenderAsHtml ()); } return null; }
void HandleWebViewFinishedLoad (object sender, WebFrameEventArgs e) { if (match != null) { ShowNode (match); match = null; } if (navigationCells.SelectedSegment != -1) navigationCells.SetSelected (false, navigationCells.SelectedSegment); var dom = e.ForFrame.DomDocument; // Update the title of the current page var elements = dom.GetElementsByTagName ("title"); if (elements.Count > 0 && !string.IsNullOrWhiteSpace (elements[0].TextContent)) currentTitle = elements[0].TextContent.Length > 2 ? elements[0].TextContent.Substring (2) : elements[0].TextContent; // Process embedded images coming from doc source // Because WebView doesn't let me answer a NSUrlRequest myself I have to resort to this piece of crap of a solution var imgs = dom.GetElementsByTagName ("img").Where (node => node.Attributes["src"].Value.StartsWith ("source-id")); byte[] buffer = new byte[4096]; foreach (var img in imgs) { var src = img.Attributes["src"].Value; var imgStream = AppDelegate.Root.GetImage (src); if (imgStream == null) continue; var length = imgStream.Read (buffer, 0, buffer.Length); var read = length; while (read != 0) { if (length == buffer.Length) { var oldBuffer = buffer; buffer = new byte[oldBuffer.Length * 2]; Buffer.BlockCopy (oldBuffer, 0, buffer, 0, oldBuffer.Length); } length += read = imgStream.Read (buffer, length, buffer.Length - length); } var data = Convert.ToBase64String (buffer, 0, length, Base64FormattingOptions.None); var uri = "data:image/" + src.Substring (src.LastIndexOf ('.')) + ";base64," + data; ((DomElement)img).SetAttribute ("src", uri); } }
public override string RenderNamespaceLookup (string nsurl, out Node match_node) { foreach (Node ns_node in Tree.Nodes){ if (ns_node.Element != nsurl) continue; match_node = ns_node; string ns_name = nsurl.Substring (2); XmlDocument doc = GetNamespaceDocument (ns_name); if (doc == null) return null; XsltArgumentList args = new XsltArgumentList(); args.AddExtensionObject("monodoc:///extensions", ExtObject); args.AddParam("show", "", "namespace"); args.AddParam("namespace", "", ns_name); string s = Htmlize(new XmlNodeReader (doc), args); return BuildHtml (css_ecma_code, js_code, s); } match_node = null; return null; }
int ScrollToVisible (Node n) { var item = nodeToWrapper [n]; var row = outlineView.RowForItem (item); outlineView.ScrollRowToVisible (row); return row; }
// // Obtain an URL of the type T:System.Object from the node // public static string GetNiceUrl (Node node) { if (node.Element.StartsWith("N:")) return node.Element; string name, full; int bk_pos = node.Caption.IndexOf (' '); // node from an overview if (bk_pos != -1) { name = node.Caption.Substring (0, bk_pos); full = node.Parent.Caption + "." + name.Replace ('.', '+'); return "T:" + full; } // node that lists constructors, methods, fields, ... if ((node.Caption == "Constructors") || (node.Caption == "Fields") || (node.Caption == "Events") || (node.Caption == "Members") || (node.Caption == "Properties") || (node.Caption == "Methods") || (node.Caption == "Operators")) { bk_pos = node.Parent.Caption.IndexOf (' '); name = node.Parent.Caption.Substring (0, bk_pos); full = node.Parent.Parent.Caption + "." + name.Replace ('.', '+'); return "T:" + full + "/" + node.Element; } int pr_pos = node.Caption.IndexOf ('('); // node from a constructor if (node.Parent.Element == "C") { name = node.Parent.Parent.Parent.Caption; int idx = node.URL.IndexOf ('/'); return node.URL[idx+1] + ":" + name + "." + node.Caption.Replace ('.', '+'); // node from a method with one signature, field, property, operator } else if (pr_pos == -1) { bk_pos = node.Parent.Parent.Caption.IndexOf (' '); name = node.Parent.Parent.Caption.Substring (0, bk_pos); full = node.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+'); int idx = node.URL.IndexOf ('/'); return node.URL[idx+1] + ":" + full + "." + node.Caption; // node from a method with several signatures } else { bk_pos = node.Parent.Parent.Parent.Caption.IndexOf (' '); name = node.Parent.Parent.Parent.Caption.Substring (0, bk_pos); full = node.Parent.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+'); int idx = node.URL.IndexOf ('/'); return node.URL[idx+1] + ":" + full + "." + node.Caption; } }