4 new revisions:
Revision: 45044b3549f1
Branch: default
Author: azizatif
Date: Wed Oct 15 05:52:25 2014 UTC
Log: Moving sources under src making it easier to create symbols
packages
https://code.google.com/p/fizzler/source/detail?r=45044b3549f1
Revision: 933b42313ad9
Branch: default
Author: azizatif
Date: Wed Oct 15 05:53:50 2014 UTC
Log: ReSharper settings migration
https://code.google.com/p/fizzler/source/detail?r=933b42313ad9
Revision: 96da88c162ef
Branch: default
Author: azizatif
Date: Wed Oct 15 06:11:06 2014 UTC
Log: Version 1.0 with source packaging
https://code.google.com/p/fizzler/source/detail?r=96da88c162ef
Revision: 0cc720824dd8
Branch: default
Author: azizatif
Date: Thu Oct 16 05:56:38 2014 UTC
Log: Added tag 1.0 for changeset 96da88c162ef
https://code.google.com/p/fizzler/source/detail?r=0cc720824dd8
==============================================================================
Revision: 45044b3549f1
Branch: default
Author: azizatif
Date: Wed Oct 15 05:52:25 2014 UTC
Log: Moving sources under src making it easier to create symbols
packages
https://code.google.com/p/fizzler/source/detail?r=45044b3549f1
Added:
/src/Common/SolutionInfo.cs
/src/ConsoleFizzler/App.config
/src/ConsoleFizzler/Command.cs
/src/ConsoleFizzler/CommandLine.cs
/src/ConsoleFizzler/ConsoleFizzler.csproj
/src/ConsoleFizzler/ExplainCommand.cs
/src/ConsoleFizzler/ICommand.cs
/src/ConsoleFizzler/NameValueCollectionExtensions.cs
/src/ConsoleFizzler/NodeOutputFormat.cs
/src/ConsoleFizzler/Program.cs
/src/ConsoleFizzler/Properties/AssemblyInfo.cs
/src/ConsoleFizzler/SelectCommand.cs
/src/ConsoleFizzler/StringExtensions.cs
/src/ConsoleFizzler/packages.config
/src/Fizzler.Sandbox/Fizzler.Sandbox.csproj
/src/Fizzler.Sandbox/Properties/AssemblyInfo.cs
/src/Fizzler.Sandbox/WinForms/ControlExtensions.cs
/src/Fizzler.Sandbox/WinForms/ControlOps.cs
/src/Fizzler.Sandbox/WinForms/ControlSelection.cs
/src/Fizzler.Sandbox/Xml/XmlNodeExtensions.cs
/src/Fizzler.Sandbox/Xml/XmlNodeOps.cs
/src/Fizzler.Sandbox/Xml/XmlNodeSelection.cs
/src/Fizzler.Systems.HtmlAgilityPack/Fizzler.Systems.HtmlAgilityPack.csproj
/src/Fizzler.Systems.HtmlAgilityPack/HtmlDocumentExtensions.cs
/src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeExtensions.cs
/src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs
/src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeSelection.cs
/src/Fizzler.Systems.HtmlAgilityPack/Properties/AssemblyInfo.cs
/src/Fizzler.Systems.HtmlAgilityPack/packages.config
/src/Fizzler.Tests/App.config
/src/Fizzler.Tests/AttributeSelectors.cs
/src/Fizzler.Tests/ChildAndAdjacentSelectors.cs
/src/Fizzler.Tests/ClassSelector.cs
/src/Fizzler.Tests/ElementSelector.cs
/src/Fizzler.Tests/Fizzler.Tests.csproj
/src/Fizzler.Tests/HumanReadableSelectorGeneratorTests.cs
/src/Fizzler.Tests/IDSelector.cs
/src/Fizzler.Tests/MultipleSelectors.cs
/src/Fizzler.Tests/NamespacePrefixTests.cs
/src/Fizzler.Tests/NthChild.cs
/src/Fizzler.Tests/NthLastChild.cs
/src/Fizzler.Tests/ParserTests.cs
/src/Fizzler.Tests/Properties/AssemblyInfo.cs
/src/Fizzler.Tests/PsuedoSelectors.cs
/src/Fizzler.Tests/ReaderTests.cs
/src/Fizzler.Tests/SelectorBaseTest.cs
/src/Fizzler.Tests/SelectorGeneratorTeeTests.cs
/src/Fizzler.Tests/SelectorTest.html
/src/Fizzler.Tests/TokenTests.cs
/src/Fizzler.Tests/TokenerTests.cs
/src/Fizzler.Tests/packages.config
/src/Fizzler/Either.cs
/src/Fizzler/Fizzler.csproj
/src/Fizzler/Fizzler.snk
/src/Fizzler/HumanReadableSelectorGenerator.cs
/src/Fizzler/IElementOps.cs
/src/Fizzler/ISelectorGenerator.cs
/src/Fizzler/NamespacePrefix.cs
/src/Fizzler/Parser.cs
/src/Fizzler/Properties/AssemblyInfo.cs
/src/Fizzler/Reader.cs
/src/Fizzler/Selector.cs
/src/Fizzler/SelectorGenerator.cs
/src/Fizzler/SelectorGeneratorTee.cs
/src/Fizzler/SelectorsCachingCompiler.cs
/src/Fizzler/Token.cs
/src/Fizzler/TokenKind.cs
/src/Fizzler/Tokener.cs
/src/NET-2.0/Fizzler.Systems.HtmlAgilityPack/Fizzler.Systems.HtmlAgilityPack.csproj
/src/NET-2.0/Fizzler.Systems.HtmlAgilityPack/packages.config
/src/NET-2.0/Fizzler.Tests/Fizzler.Tests.csproj
/src/NET-2.0/Fizzler.Tests/packages.config
/src/NET-2.0/Fizzler/Fizzler.csproj
/src/NET-2.0/Fizzler/packages.config
/src/VisualFizzler/CursorScope.cs
/src/VisualFizzler/ISingletonScopeHelper.cs
/src/VisualFizzler/MainForm.Designer.cs
/src/VisualFizzler/MainForm.cs
/src/VisualFizzler/MainForm.resx
/src/VisualFizzler/Program.cs
/src/VisualFizzler/Properties/AssemblyInfo.cs
/src/VisualFizzler/Properties/Resources.Designer.cs
/src/VisualFizzler/Properties/Resources.resx
/src/VisualFizzler/Properties/Settings.Designer.cs
/src/VisualFizzler/Properties/Settings.settings
/src/VisualFizzler/SingletonScope.cs
/src/VisualFizzler/VisualFizzler.csproj
/src/VisualFizzler/WebClient.cs
/src/VisualFizzler/packages.config
Deleted:
/Common/SolutionInfo.cs
/ConsoleFizzler/App.config
/ConsoleFizzler/Command.cs
/ConsoleFizzler/CommandLine.cs
/ConsoleFizzler/ConsoleFizzler.csproj
/ConsoleFizzler/ExplainCommand.cs
/ConsoleFizzler/ICommand.cs
/ConsoleFizzler/NameValueCollectionExtensions.cs
/ConsoleFizzler/NodeOutputFormat.cs
/ConsoleFizzler/Program.cs
/ConsoleFizzler/Properties/AssemblyInfo.cs
/ConsoleFizzler/SelectCommand.cs
/ConsoleFizzler/StringExtensions.cs
/ConsoleFizzler/packages.config
/Fizzler.Sandbox/Fizzler.Sandbox.csproj
/Fizzler.Sandbox/Properties/AssemblyInfo.cs
/Fizzler.Sandbox/WinForms/ControlExtensions.cs
/Fizzler.Sandbox/WinForms/ControlOps.cs
/Fizzler.Sandbox/WinForms/ControlSelection.cs
/Fizzler.Sandbox/Xml/XmlNodeExtensions.cs
/Fizzler.Sandbox/Xml/XmlNodeOps.cs
/Fizzler.Sandbox/Xml/XmlNodeSelection.cs
/Fizzler.Systems.HtmlAgilityPack/Fizzler.Systems.HtmlAgilityPack.csproj
/Fizzler.Systems.HtmlAgilityPack/HtmlDocumentExtensions.cs
/Fizzler.Systems.HtmlAgilityPack/HtmlNodeExtensions.cs
/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs
/Fizzler.Systems.HtmlAgilityPack/HtmlNodeSelection.cs
/Fizzler.Systems.HtmlAgilityPack/Properties/AssemblyInfo.cs
/Fizzler.Systems.HtmlAgilityPack/packages.config
/Fizzler.Tests/App.config
/Fizzler.Tests/AttributeSelectors.cs
/Fizzler.Tests/ChildAndAdjacentSelectors.cs
/Fizzler.Tests/ClassSelector.cs
/Fizzler.Tests/ElementSelector.cs
/Fizzler.Tests/Fizzler.Tests.csproj
/Fizzler.Tests/HumanReadableSelectorGeneratorTests.cs
/Fizzler.Tests/IDSelector.cs
/Fizzler.Tests/MultipleSelectors.cs
/Fizzler.Tests/NamespacePrefixTests.cs
/Fizzler.Tests/NthChild.cs
/Fizzler.Tests/NthLastChild.cs
/Fizzler.Tests/ParserTests.cs
/Fizzler.Tests/Properties/AssemblyInfo.cs
/Fizzler.Tests/PsuedoSelectors.cs
/Fizzler.Tests/ReaderTests.cs
/Fizzler.Tests/SelectorBaseTest.cs
/Fizzler.Tests/SelectorGeneratorTeeTests.cs
/Fizzler.Tests/SelectorTest.html
/Fizzler.Tests/TokenTests.cs
/Fizzler.Tests/TokenerTests.cs
/Fizzler.Tests/packages.config
/Fizzler/Either.cs
/Fizzler/Fizzler.csproj
/Fizzler/Fizzler.snk
/Fizzler/HumanReadableSelectorGenerator.cs
/Fizzler/IElementOps.cs
/Fizzler/ISelectorGenerator.cs
/Fizzler/NamespacePrefix.cs
/Fizzler/Parser.cs
/Fizzler/Properties/AssemblyInfo.cs
/Fizzler/Reader.cs
/Fizzler/Selector.cs
/Fizzler/SelectorGenerator.cs
/Fizzler/SelectorGeneratorTee.cs
/Fizzler/SelectorsCachingCompiler.cs
/Fizzler/Token.cs
/Fizzler/TokenKind.cs
/Fizzler/Tokener.cs
/NET-2.0/Fizzler.Systems.HtmlAgilityPack/Fizzler.Systems.HtmlAgilityPack.csproj
/NET-2.0/Fizzler.Systems.HtmlAgilityPack/packages.config
/NET-2.0/Fizzler.Tests/Fizzler.Tests.csproj
/NET-2.0/Fizzler.Tests/packages.config
/NET-2.0/Fizzler/Fizzler.csproj
/NET-2.0/Fizzler/packages.config
/VisualFizzler/CursorScope.cs
/VisualFizzler/ISingletonScopeHelper.cs
/VisualFizzler/MainForm.Designer.cs
/VisualFizzler/MainForm.cs
/VisualFizzler/MainForm.resx
/VisualFizzler/Program.cs
/VisualFizzler/Properties/AssemblyInfo.cs
/VisualFizzler/Properties/Resources.Designer.cs
/VisualFizzler/Properties/Resources.resx
/VisualFizzler/Properties/Settings.Designer.cs
/VisualFizzler/Properties/Settings.settings
/VisualFizzler/SingletonScope.cs
/VisualFizzler/VisualFizzler.csproj
/VisualFizzler/WebClient.cs
/VisualFizzler/packages.config
Modified:
/Fizzler.sln
=======================================
--- /dev/null
+++ /src/Common/SolutionInfo.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,62 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+using System.Reflection;
+using CLSCompliantAttribute = System.CLSCompliantAttribute;
+using ComVisible = System.Runtime.InteropServices.ComVisibleAttribute;
+
+//
+// General description
+//
+
+[assembly: AssemblyProduct("Fizzler")]
+[assembly: AssemblyCompany("
http://fizzler.googlecode.com")]
+[assembly: AssemblyCopyright("Copyright (c) 2009 Atif Aziz, Colin Ramsay.
All rights reserved.")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information
+//
+
+[assembly: AssemblyVersion("0.1.15619.0")]
+[assembly: AssemblyInformationalVersion("1.015619.0")]
+
+//
+// Configuration (test, debug, release)
+//
+
+#if TEST
+ #if !DEBUG
+ #warning Test builds should be compiled using the DEBUG configuration.
+ #endif
+ [assembly: AssemblyConfiguration("Test")]
+#elif DEBUG
+ [assembly: AssemblyConfiguration("Debug")]
+#else
+ [assembly: AssemblyConfiguration("Release")]
+#endif
+
+//
+// COM visibility and CLS compliance
+//
+
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(true)]
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/App.config Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <appSettings>
+ <add key="SelectCommand.TagColor" value="Cyan" />
+ <add key="SelectCommand.AttributeNameColor" value="Yellow" />
+ <add key="SelectCommand.AttributeValueColor" value="Green" />
+ <add key="SelectCommand.CommentColor" value="Gray" />
+ </appSettings>
+</configuration>
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/Command.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,59 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ using System;
+ using System.Configuration;
+
+ internal abstract class Command : ICommand
+ {
+ public int Run(string[] args)
+ {
+ LoadConfiguration();
+ var tail = CommandLine.ParseTo(args, this);
+ return OnRun(tail);
+ }
+
+ protected void LoadConfiguration()
+ {
+ LoadConfiguration(GetType().Name);
+ }
+
+ /// <summary>
+ /// Maps application settings into command line arguments.
+ /// </summary>
+ /// <param name="prefix"></param>
+ protected virtual void LoadConfiguration(string prefix)
+ {
+ if (prefix == null) throw new ArgumentNullException("prefix");
+
+ if (prefix.Length > 0)
+ prefix = prefix + ".";
+
+ var settings = ConfigurationManager.AppSettings;
+ var args = CommandLine.ToArgs(settings.Narrow(prefix).Pairs());
+ CommandLine.ParseTo(args, this);
+ }
+
+ protected abstract int OnRun(string[] args);
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/CommandLine.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,257 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.IO;
+ using System.Linq;
+ using System.Runtime.InteropServices;
+ using Mannex;
+
+
+ #endregion
+
+ static class CommandLine
+ {
+ private static readonly char[] _argSeparators = new[] { ':', '=' };
+
+ /// <summary>
+ /// Updates object from command-line arguments in a response file.
+ /// </summary>
+ /// <remarks>
+ /// Line in the response file that begin with a hash (#) are
+ /// considered as comments.
+ /// </remarks>
+
+ public static string[] ParseFileTo(string path, object target)
+ {
+ return ParseFileTo(path, target, null);
+ }
+
+ /// <summary>
+ /// Updates object from command-line arguments in a response file
+ /// <paramref name="properties" /> describes the target object.
+ /// </summary>
+ /// <remarks>
+ /// Line in the response file that begin with a hash (#) are
+ /// considered as comments.
+ /// </remarks>
+
+ public static string[] ParseFileTo(string path, object target,
PropertyDescriptorCollection properties)
+ {
+ if (path == null) throw new ArgumentNullException("path");
+ if (target == null) throw new ArgumentNullException("target");
+
+ var lines = File.ReadAllLines(path)
+ .Where(line => line.Length > 0 &&
line[0] != '#'); // except comments
+
+ var args = CommandLineToArgs(string.Join(" ",
lines.ToArray()));
+
+ return ParseTo(args, target, null);
+ }
+
+ /// <summary>
+ /// Updates object from command-line arguments.
+ /// </summary>
+
+ public static string[] ParseTo(IEnumerable<string> args, object
target)
+ {
+ return ParseTo(args, target, null);
+ }
+
+ /// <summary>
+ /// Updates object from command-line arguments where
+ /// <paramref name="properties" /> describes the target object.
+ /// </summary>
+
+ public static string[] ParseTo(IEnumerable<string> args, object
target, PropertyDescriptorCollection properties)
+ {
+ if (target == null) throw new ArgumentNullException("target");
+ if (args == null) throw new ArgumentNullException("args");
+
+ var tails = new List<string>();
+
+ var e = args.GetEnumerator();
+ while (e.MoveNext())
+ {
+ var arg = e.Current;
+
+ if (arg.Length == 0) // empty arg?
+ {
+ tails.Add(arg);
+ continue;
+ }
+
+ // Get argument name, Unix or DOS style.
+
+ string name;
+
+ if (arg[0] == '/') // DOS style
+ {
+ name = arg.Substring(1);
+ }
+ else if (arg.Length > 1 && arg[0] == '-' && arg[1] == '-')
// Unix style
+ {
+ if (arg.Length == 2) // comment
+ break;
+ name = arg.Substring(2);
+ }
+ else
+ {
+ tails.Add(arg); // anonymous argument
+ continue;
+ }
+
+ // Is the argument name and value paired in one?
+ // Allows `arg=value` or `arg:value` style.
+
+ var paired = name.IndexOfAny(_argSeparators) > 0;
+ var pair = name.Split(_argSeparators, (n, v) => new { Name
= n, Value = v });
+
+ if (paired)
+ name = pair.Name; // Break the name out of the pair
+
+ // Get setting property from name.
+
+ var propertyName = name.Replace("-", " ")
+ .ToTitleCaseInvariant()
+ .Replace(" ", string.Empty);
+
+ if (properties == null)
+ properties = TypeDescriptor.GetProperties(target);
+
+ var property = properties.Find(propertyName, true);
+
+ if (property == null)
+ throw new FormatException(string.Format("Unknown
command-line argument: " + name));
+
+ // Process argument based on property type.
+
+ var type = property.PropertyType;
+ object value;
+
+ if (type == typeof(bool)) // Boolean?
+ {
+ value = true; // flag-style
+ }
+ else
+ {
+ // If value was paired with name then break out the
value
+ // from the pair other read it from the next argument.
+
+ if (paired)
+ {
+ value = pair.Value;
+ }
+ else
+ {
+ if (!e.MoveNext())
+ throw new FormatException("Missing value for
command-line argument: " + name);
+
+ value = e.Current;
+ }
+
+ // If property is of another type than string and it
+ // support conversion then do that now.
+
+ if (type != typeof(string))
+ {
+ var converter = property.Converter ??
TypeDescriptor.GetConverter(type);
+
+ if (!converter.CanConvertFrom(typeof(string)))
+ throw new FormatException("Unsupported
command-line argument:" + name);
+
+ value =
converter.ConvertFromString(value.ToString());
+ }
+ }
+
+ property.SetValue(target, value);
+ }
+
+ return tails.ToArray();
+ }
+
+ [DllImport("shell32.dll", SetLastError = true)]
+ static extern IntPtr CommandLineToArgvW(
+ [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int
pNumArgs);
+
+ private static string[] CommandLineToArgs(string commandLine)
+ {
+ int argc;
+ var argv = CommandLineToArgvW(commandLine, out argc);
+ if (argv == IntPtr.Zero)
+ throw new Win32Exception();
+ try
+ {
+ var args = new string[argc];
+ for (var i = 0; i < args.Length; i++)
+ {
+ var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
+ args[i] = Marshal.PtrToStringUni(p);
+ }
+
+ return args;
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(argv);
+ }
+ }
+
+ /// <summary>
+ /// Returns a sequence of args from a sequence of pair where each
+ /// key is prefixed with a switch token classic for the platform.
+ /// </summary>
+ public static IEnumerable<string>
ToArgs(IEnumerable<KeyValuePair<string, string>> args)
+ {
+ return ToArgs(args, null);
+ }
+
+ /// <summary>
+ /// Returns a sequence of args from a sequence of pair where each
+ /// key is prefixed with <paramref name="switchToken"/>.
+ /// </summary>
+ public static IEnumerable<string>
ToArgs(IEnumerable<KeyValuePair<string, string>> args, string switchToken)
+ {
+ if (args == null) throw new ArgumentNullException("args");
+
+ if (string.IsNullOrEmpty(switchToken))
+ {
+ var platform = Environment.OSVersion.Platform;
+ switchToken = platform == PlatformID.Unix ? "--" : "/";
+ }
+
+ return ArgsFromImpl(args, switchToken);
+ }
+
+ private static IEnumerable<string>
ArgsFromImpl(IEnumerable<KeyValuePair<string, string>> args,
+ string switchToken)
+ {
+ return args.Select(e => new[] { switchToken + e.Key, e.Value })
+ .SelectMany(e => e);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/ConsoleFizzler.csproj Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)'
== '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{296C2824-A7D7-42A0-9B4C-1BC8FA0A1859}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ConsoleFizzler</RootNamespace>
+ <AssemblyName>fizz</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir)
== '*Undefined*'">..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|
AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|
AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="HtmlAgilityPack, Version=1.4.6.0, Culture=neutral,
PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+
<HintPath>..\..\packages\HtmlAgilityPack.1.4.6\lib\Net20\HtmlAgilityPack.dll</HintPath>
+ </Reference>
+ <Reference Include="Mannex, Version=1.7.15616.0, Culture=neutral,
processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\packages\Mannex.1.7.0\lib\net35\Mannex.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.XML" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Common\SolutionInfo.cs">
+ <Link>SolutionInfo.cs</Link>
+ </Compile>
+ <Compile Include="CommandLine.cs" />
+ <Compile Include="Command.cs" />
+ <Compile Include="ExplainCommand.cs" />
+ <Compile Include="ICommand.cs" />
+ <Compile Include="NameValueCollectionExtensions.cs" />
+ <Compile Include="NodeOutputFormat.cs" />
+ <Compile Include="SelectCommand.cs" />
+ <Compile Include="StringExtensions.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference
Include="..\Fizzler.Systems.HtmlAgilityPack\Fizzler.Systems.HtmlAgilityPack.csproj">
+ <Project>{DBEAD205-BD5C-461F-873D-DE643016F14C}</Project>
+
<Name>Fizzler.Systems.HtmlAgilityPack %28Systems\Fizzler.Systems.HtmlAgilityPack%29</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Fizzler\Fizzler.csproj">
+ <Project>{939036D6-29FD-46E4-B6CD-52618F51081B}</Project>
+ <Name>Fizzler</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+ <!-- To modify your build process, add your task inside one of the
targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/ExplainCommand.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,45 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System;
+ using System.Linq;
+ using Fizzler;
+
+ #endregion
+
+ internal sealed class ExplainCommand : Command
+ {
+ protected override int OnRun(string[] args)
+ {
+ if (!args.Any())
+ throw new ApplicationException("Missing CSS selector.");
+
+ var generator = new HumanReadableSelectorGenerator();
+ Parser.Parse(args[0], generator);
+ Console.WriteLine(generator.Text);
+ return 0;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/ICommand.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,28 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ internal interface ICommand
+ {
+ int Run(string[] args);
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/NameValueCollectionExtensions.cs Wed Oct 15
05:52:25 2014 UTC
@@ -0,0 +1,87 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Specialized;
+ using System.Linq;
+
+ #endregion
+
+ static class NameValueCollectionExtensions
+ {
+ public static IEnumerable<string> KeysByPrefix(this
NameValueCollection collection, string prefix)
+ {
+ return KeysByPrefix(collection, prefix,
StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ public static IEnumerable<string> KeysByPrefix(this
NameValueCollection collection, string prefix, StringComparison comparison)
+ {
+ if(collection == null) throw new
ArgumentNullException("collection");
+
+ return string.IsNullOrEmpty(prefix)
+ ? collection.Keys.Cast<string>()
+ : KeysByPrefixImpl(collection, prefix, comparison);
+ }
+
+ private static IEnumerable<string>
KeysByPrefixImpl(NameValueCollection collection, string prefix,
StringComparison comparison)
+ {
+ return from string key in collection.AllKeys
+ where key != null
+ && key.Length > prefix.Length
+ && key.StartsWith(prefix, comparison)
+ select key;
+ }
+
+ public static IEnumerable<KeyValuePair<string, string>> Pairs(this
NameValueCollection collection)
+ {
+ if (collection == null) throw new
ArgumentNullException("collection");
+ return collection.Keys.Cast<string>()
+ .Select(key => new KeyValuePair<string,
string>(key, collection[key]));
+ }
+
+ public static NameValueCollection Narrow(this NameValueCollection
collection, string prefix)
+ {
+ if (collection == null) throw new
ArgumentNullException("collection");
+
+ if (string.IsNullOrEmpty(prefix))
+ return collection;
+
+ var result = new NameValueCollection();
+ var entries = from key in collection.KeysByPrefix(prefix)
+ let values = collection.GetValues(key)
+ where values != null
+ select new { Key = key.Substring(prefix.Length),
Values = values };
+
+ foreach (var entry in entries)
+ {
+ foreach(var value in entry.Values)
+ result.Add(entry.Key, value);
+ }
+
+ return result;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/NodeOutputFormat.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,31 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ internal enum NodeOutputFormat
+ {
+ Default,
+ TagName,
+ BeginTag,
+ Full
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/Program.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,77 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using Mannex.Collections.Generic;
+
+ #endregion
+
+ internal static class Program
+ {
+ internal static int Main(string[] args)
+ {
+ try
+ {
+ return Run(args);
+ }
+ catch (Exception e)
+ {
+ Console.Error.WriteLine(e.Message);
+ Trace.TraceError(e.ToString());
+ return 100;
+ }
+ }
+
+ static int Run(string[] args)
+ {
+ if (args.Length == 0)
+ throw new ApplicationException("Missing command.");
+
+ var commands = new[]
+ {
+ new Func<ICommand>(() => new
SelectCommand()).AsKeyTo(Aliases("select", "sel")),
+ new Func<ICommand>(() => new
ExplainCommand()).AsKeyTo(Aliases("explain", "describe", "desc")),
+ }
+ .SelectMany(e => e.Value.Select(v => v.AsKeyTo(e.Key)))
+ .ToDictionary(e => e.Key, e => e.Value);
+
+ var name = args[0];
+
+ var command = commands.Find(name);
+ if (command == null)
+ throw new ApplicationException("Invalid command.");
+
+ return command().Run(args.Skip(1).ToArray());
+ }
+
+ static IEnumerable<string> Aliases(params string[] values)
+ {
+ return values;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/Properties/AssemblyInfo.cs Wed Oct 15 05:52:25 2014
UTC
@@ -0,0 +1,31 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+using System.Reflection;
+
+[assembly: AssemblyTitle("ConsoleFizzler")]
+[assembly: AssemblyDescription("Fizzler Console Application")]
+
+//
+// Version information
+//
+
+[assembly: AssemblyFileVersion("1.0.15619.2054")]
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/SelectCommand.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,169 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using Fizzler.Systems.HtmlAgilityPack;
+ using HtmlAgilityPack;
+
+ #endregion
+
+ internal sealed class SelectCommand : Command
+ {
+ private string _separator;
+
+ public bool Colorful { get; set; }
+ public ConsoleColor? TagNameColor { get; set; }
+ public ConsoleColor? TagColor { get; set; }
+ public ConsoleColor? AttributeNameColor { get; set; }
+ public ConsoleColor? AttributeValueColor { get; set; }
+ public ConsoleColor? AttributeColor { get; set; }
+ public ConsoleColor? CommentColor { get; set; }
+
+ public string Separator
+ {
+ get { return _separator ?? string.Empty; }
+ set { _separator = value; }
+ }
+
+ public bool LineInfo { get; set; }
+
+ public NodeOutputFormat OutputFormat { get; set; }
+
+ protected override int OnRun(string[] args)
+ {
+ if (OutputFormat != NodeOutputFormat.Default
+ && OutputFormat != NodeOutputFormat.Full)
+ Console.Error.WriteLine("WARNING! The output format option
is not yet supported.");
+
+ var arg = ((IEnumerable<string>)args).GetEnumerator();
+
+ if (!arg.MoveNext())
+ throw new ApplicationException("Missing CSS selector.");
+
+ var selector = arg.Current;
+
+ var document = new HtmlDocument();
+ if(!arg.MoveNext() || arg.Current == "-")
+ document.LoadHtml2(Console.In.ReadToEnd());
+ else
+ document.Load2(arg.Current);
+
+ var i = 0;
+ foreach (var node in
document.DocumentNode.QuerySelectorAll(selector))
+ {
+ if (i > 0 && Separator.Length > 0)
+ Console.WriteLine(Separator);
+
+ if (LineInfo)
+ Console.Write("@{0},{1}: ", node.Line,
node.LinePosition);
+
+ Output(node);
+ Console.WriteLine();
+ i++;
+ }
+
+ //
+ // Exit code = 0 (found) or 1 (not found)
+ //
+
+ return i > 0 ? 0 : 1;
+ }
+
+ private void Output(HtmlNode node)
+ {
+ var color = Console.ForegroundColor;
+
+ try
+ {
+ OutputImpl(node, color);
+ }
+ finally
+ {
+ if (Colorful)
+ Console.ForegroundColor = color;
+ }
+ }
+
+ private void OutputImpl(HtmlNode node, ConsoleColor color)
+ {
+ Debug.Assert(node.NodeType == HtmlNodeType.Element);
+
+ Write(TagColor ?? color, "<");
+ Write(TagNameColor ?? TagColor ?? color, node.Name);
+
+ foreach (var attribute in node.Attributes)
+ {
+ Write(color, " ");
+ Write(AttributeNameColor ?? AttributeColor ?? color,
attribute.Name);
+ Write(AttributeColor ?? color, "=\"");
+ Write(AttributeValueColor ?? AttributeColor ?? color,
HtmlDocument.HtmlEncode(attribute.Value));
+ Write(AttributeColor ?? color, "\"");
+ }
+
+ var descendants = node.Descendants();
+ if (!descendants.Any())
+ {
+ Write(color, " ");
+ Write(TagColor ?? color, "/>");
+ }
+ else
+ {
+ Write(TagColor ?? color, ">");
+
+ foreach (var descendant in descendants)
+ {
+ var type = descendant.NodeType;
+ switch(type)
+ {
+ case HtmlNodeType.Element:
+ Output(descendant);
+ break;
+ case HtmlNodeType.Comment:
+ Write(CommentColor ?? color,
descendant.OuterHtml);
+ break;
+ default:
+ Write(color, descendant.OuterHtml);
+ break;
+ }
+ }
+
+ Write(TagColor ?? color, "</");
+ Write(TagNameColor ?? TagColor ?? color, node.Name);
+ Write(TagColor ?? color, ">");
+ }
+ }
+
+ private void Write(ConsoleColor color, params string[] strings)
+ {
+ if (Colorful)
+ Console.ForegroundColor = color;
+
+ Array.ForEach(strings, Console.Write);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/StringExtensions.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,50 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace ConsoleFizzler
+{
+ #region Imports
+
+ using System.Globalization;
+
+ #endregion
+
+ static class StringExtensions
+ {
+ /// <summary>
+ /// Converts the specified string to titlecase using the invariant
culture.
+ /// </summary>
+
+ public static string ToTitleCaseInvariant(this string str)
+ {
+ return ToTitleCase(str, CultureInfo.InvariantCulture.TextInfo);
+ }
+
+ /// <summary>
+ /// Converts the specified string to titlecase.
+ /// </summary>
+
+ public static string ToTitleCase(this string str, TextInfo info)
+ {
+ return (info ??
CultureInfo.CurrentCulture.TextInfo).ToTitleCase(str);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/ConsoleFizzler/packages.config Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="HtmlAgilityPack" version="1.4.6" targetFramework="net35" />
+ <package id="Mannex" version="1.7.0" targetFramework="net35" />
+</packages>
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/Fizzler.Sandbox.csproj Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)'
== '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{80456F6D-6853-4244-8E3D-F22ECA0980EC}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Fizzler</RootNamespace>
+ <AssemblyName>Fizzler.Sandbox</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|
AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|
AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Common\SolutionInfo.cs">
+ <Link>SolutionInfo.cs</Link>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="WinForms\ControlExtensions.cs" />
+ <Compile Include="WinForms\ControlOps.cs" />
+ <Compile Include="WinForms\ControlSelection.cs" />
+ <Compile Include="Xml\XmlNodeExtensions.cs" />
+ <Compile Include="Xml\XmlNodeOps.cs" />
+ <Compile Include="Xml\XmlNodeSelection.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Fizzler\Fizzler.csproj">
+ <Project>{939036D6-29FD-46E4-B6CD-52618F51081B}</Project>
+ <Name>Fizzler</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the
targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/Properties/AssemblyInfo.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,31 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+using System.Reflection;
+
+[assembly: AssemblyTitle("Fizzler.Sandbox")]
+[assembly: AssemblyDescription("Fizzler sandbox for experiments and
futures")]
+
+//
+// Version information
+//
+
+[assembly: AssemblyFileVersion("1.0.15619.2054")]
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/WinForms/ControlExtensions.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,134 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.WinForms
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Windows.Forms;
+
+ #endregion
+
+ /// <summary>
+ /// Extension methods for <see cref="Control"/>.
+ /// </summary>
+ public static class ControlExtensions
+ {
+ /// <summary>
+ /// Returns a collection of all properties on the control.
+ /// </summary>
+ public static PropertyDescriptorCollection Properties(this Control
control)
+ {
+ if (control == null) throw new
ArgumentNullException("control");
+ return TypeDescriptor.GetProperties(control);
+ }
+
+ /// <summary>
+ /// Attemps to locate a property on the object and returns its
value.
+ /// If the property does not exist then a null reference is
returned.
+ /// </summary>
+ public static object FindPropertyValue(this Control control,
string name)
+ {
+ return FindPropertyValue(control, name, null);
+ }
+
+ /// <summary>
+ /// Attemps to locate a property on the object and returns its
value.
+ /// If the property does not exist then the value specified in
+ /// <paramref name="defaultValue"/> is returned instead.
+ /// </summary>
+ public static object FindPropertyValue(this Control control,
string name, object defaultValue)
+ {
+ if (control == null) throw new
ArgumentNullException("control");
+ var property =
TypeDescriptor.GetProperties(control).Find(name, true);
+ return property == null ? defaultValue :
property.GetValue(control);
+ }
+
+ /// <summary>
+ /// Attemps to locate a property on the object and returns a string
+ /// representation of its value. If the property does not exist
then
+ /// an empty string is returned but never a null reference.
+ /// </summary>
+ internal static string FindPropertyValueString(this Control
control, string name)
+ {
+ return Convert.ToString(control.FindPropertyValue(name) ??
string.Empty);
+ }
+
+ /// <summary>
+ /// Returns a collection of all controls that precede this control
+ /// in children of its parent.
+ /// </summary>
+ public static IEnumerable<Control> ControlsAfterSelf(this Control
control)
+ {
+ if (control == null) throw new
ArgumentNullException("control");
+ var parent = control.Parent;
+ if (parent != null)
+ {
+ var controls = parent.Controls;
+ var i = controls.IndexOf(control) + 1;
+ for (; i < controls.Count; i++)
+ yield return controls[i];
+ }
+ }
+
+ /// <summary>
+ /// Returns a collection of all controls that succeed this control
+ /// in children of its parent.
+ /// </summary>
+ public static IEnumerable<Control> ControlsBeforeSelf(this Control
control)
+ {
+ if (control == null) throw new
ArgumentNullException("control");
+ var parent = control.Parent;
+ if (parent != null)
+ {
+ var controls = parent.Controls;
+ var count = controls.IndexOf(control);
+ for (var i = 0; i < count; i++)
+ yield return controls[i];
+ }
+ }
+
+ /// <summary>
+ /// Returns a collection of all controls that are the children and
+ /// grandchildren of this control.
+ /// </summary>
+ public static IEnumerable<Control> Descendants(this Control
control)
+ {
+ if (control == null) throw new
ArgumentNullException("control");
+ return DescendantsImpl(control);
+ }
+
+ private static IEnumerable<Control> DescendantsImpl(Control
control)
+ {
+ Debug.Assert(control != null);
+ foreach (Control child in control.Controls)
+ {
+ yield return child;
+ foreach (var descendant in child.Descendants())
+ yield return descendant;
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/WinForms/ControlOps.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,277 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.WinForms
+{
+ #region Imports
+
+ using System;
+ using System.Linq;
+ using System.Windows.Forms;
+
+ #endregion
+
+ /// <summary>
+ /// An <see cref="IElementOps{TElement}"/> implementation for <see
cref="Control"/>
+ /// from Windows Forms.
+ /// </summary>
+ public class ControlOps : IElementOps<Control>
+ {
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#type-selectors">type
selector</a>,
+ /// which represents an instance of the control type in the
control tree.
+ /// </summary>
+ /// <remarks>
+ /// This selector only checks on the name portion of the control's
+ /// run-time type. If the <paramref name="type"/> contains dashes
+ /// then they are used to make stricter checks across the namespace
+ /// as well. For example, if <paramref name="type"/> is
+ /// <c>button</c> then it will match against all controls whose
+ /// run-time type name is <c>button</c>, regardless of case and
+ /// namespace. Suppose, however, there are two controls of type
+ /// <c>Foo.Bar.Button</c> and <c>Baz.Qux.Button</c>. A type
+ /// selection for <c>button</c> will yield instances of both.
+ /// A type selection for <c>bar-button</c> or <c>foo-bar-button</c>
+ /// on the other hand will yield instance of <c>Foo.Bar.Button</c>.
+ /// In essence, <paramref name="type"/> represent the
<em>tail</em>.
+ /// </remarks>
+ public virtual Selector<Control> Type(NamespacePrefix prefix,
string type)
+ {
+ // TODO Proper namespace support
+ return TypeEndsWith(type.Split('-').Reverse().ToArray());
+ }
+
+ private static Selector<Control> TypeEndsWith(string[] names)
+ {
+ return controls => controls.Where(c => c.GetType().FullName
+ .Split('.')
+ .Reverse()
+ .Take(names.Length)
+ .SequenceEqual(names,
StringComparer.InvariantCultureIgnoreCase));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#universal-selector">universal
selector</a>,
+ /// any single control in the control tree.
+ /// </summary>
+ public virtual Selector<Control> Universal(NamespacePrefix prefix)
+ {
+ // TODO Proper namespace support
+ return controls => controls;
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#Id-selectors">ID selector</a>,
+ /// which represents a control instance that has an identifier that
+ /// matches the identifier in the ID selector.
+ /// </summary>
+ public virtual Selector<Control> Id(string id)
+ {
+ return controls => controls.Where(c => c.Name == id);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#class-html">class selector</a>,
+ /// which is an alternative <see
cref="IElementOps{TElement}.AttributeIncludes"/> when
+ /// representing the <c>class</c> attribute.
+ /// </summary>
+ public virtual Selector<Control> Class(string clazz)
+ {
+ return AttributeIncludes(NamespacePrefix.None, "class", clazz);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents a control with the given property <paramref
name="name"/>
+ /// whatever the values of the property.
+ /// </summary>
+ public virtual Selector<Control> AttributeExists(NamespacePrefix
prefix, string name)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.Properties().Find(name, true) != null);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents a control with the given property <paramref
name="name"/>
+ /// and whose value is exactly <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<Control> AttributeExact(NamespacePrefix
prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name) == value);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents a control with the given property <paramref
name="name"/>
+ /// and whose value is a whitespace-separated list of words, one of
+ /// which is exactly <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<Control> AttributeIncludes(NamespacePrefix
prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name).Split().Contains(value));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents a control with the given property <paramref
name="name"/>,
+ /// its value either being exactly <paramref name="value"/> or
beginning
+ /// with <paramref name="value"/> immediately followed by "-"
(U+002D).
+ /// </summary>
+ public virtual Selector<Control>
AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name).Split('-').Contains(value));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an control with the attribute <paramref
name="name"/>
+ /// whose value begins with the prefix <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<Control>
AttributePrefixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name).StartsWith(value));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an control with the attribute <paramref
name="name"/>
+ /// whose value ends with the suffix <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<Control>
AttributeSuffixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name).EndsWith(value));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the attribute <paramref
name="name"/>
+ /// whose value contains at least one instance of the substring
<paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<Control>
AttributeSubstring(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return controls => controls.Where(c =>
c.FindPropertyValueString(name).Contains(value));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents a control that is the first child of some
other control.
+ /// </summary>
+ public virtual Selector<Control> FirstChild()
+ {
+ return controls => controls.Where(c
=> !c.ControlsBeforeSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents a control that is the last child of some
other control.
+ /// </summary>
+ public virtual Selector<Control> LastChild()
+ {
+ return controls => controls.Where(c
=> !c.ControlsAfterSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents a control that is the N-th child of some
other control.
+ /// </summary>
+ public virtual Selector<Control> NthChild(int position, int i)
+ {
+ return controls => from c in controls
+ let parent = c.Parent
+ where parent != null
+ let siblings = parent.Controls
+ where siblings.IndexOf(c) == position - 1
+ select c;
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents a control that has a parent control and whose
parent
+ /// control has no other children.
+ /// </summary>
+ public virtual Selector<Control> OnlyChild()
+ {
+ return controls => controls.Where(c
=> !c.ControlsBeforeSelf().Concat(c.ControlsAfterSelf()).Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents a control that has no children at all.
+ /// </summary>
+ public virtual Selector<Control> Empty()
+ {
+ return controls => controls.Where(c => c.Controls.Count == 0);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a childhood relationship between two controls.
+ /// </summary>
+ public virtual Selector<Control> Child()
+ {
+ return controls => controls.SelectMany(c =>
c.Controls.Cast<Control>());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a relationship between two controls where one
control is an
+ /// arbitrary descendant of some ancestor control.
+ /// </summary>
+ public virtual Selector<Control> Descendant()
+ {
+ return controls => controls.SelectMany(c => c.Descendants());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents controls that share the same parent in the
document tree and
+ /// where the first control immediately precedes the second
control.
+ /// </summary>
+ public virtual Selector<Control> Adjacent()
+ {
+ return controls => controls.SelectMany(c =>
c.ControlsAfterSelf().Take(1));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<Control> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ControlsAfterSelf());
+ }
+
+ public Selector<Control> NthLastChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/WinForms/ControlSelection.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,60 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.WinForms
+{
+ #region Imports
+
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Windows.Forms;
+
+ #endregion
+
+ /// <summary>
+ /// Selectors API for <see cref="Control"/>.
+ /// </summary>
+ /// <remarks>
+ /// For more information, see <a
href="
http://www.w3.org/TR/selectors-api/">Selectors API</a>.
+ /// </remarks>
+ public static class ControlSelection
+ {
+ /// <summary>
+ /// Similar to <see cref="QuerySelectorAll" /> except it returns
+ /// only the first control matching the supplied selector strings.
+ /// </summary>
+ public static Control QuerySelector(this Control control, string
selector)
+ {
+ return
Enumerable.FirstOrDefault(control.QuerySelectorAll(selector));
+ }
+
+ /// <summary>
+ /// Retrieves all controls from descendants of the starting control
+ /// that match any selector within the supplied selector strings.
+ /// </summary>
+ public static IEnumerable<Control> QuerySelectorAll(this Control
control, string selector)
+ {
+ var generator = new SelectorGenerator<Control>(new
ControlOps());
+ Parser.Parse(selector, generator);
+ return generator.Selector(Enumerable.Repeat(control, 1));
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/Xml/XmlNodeExtensions.cs Wed Oct 15 05:52:25 2014
UTC
@@ -0,0 +1,141 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.XmlNodeQuery
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Xml;
+
+ #endregion
+
+ public static class XmlNodeExtensions
+ {
+ /// <summary>
+ /// Determines whether this node is an element or not.
+ /// </summary>
+ public static bool IsElement(this XmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodeType == XmlNodeType.Element;
+ }
+
+ /// <summary>
+ /// Returns a collection of elements from this collection.
+ /// </summary>
+ public static IEnumerable<XmlNode> Elements(this
IEnumerable<XmlNode> nodes)
+ {
+ if (nodes == null) throw new ArgumentNullException("nodes");
+ return nodes.Where(n => n.IsElement());
+ }
+
+ /// <summary>
+ /// Returns a collection of child nodes of this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> Children(this XmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.ChildNodes.Cast<XmlNode>();
+ }
+
+
+ /// <summary>
+ /// Returns a collection of child elements of this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> Elements(this XmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.Children().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling elements after this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> ElementsAfterSelf(this XmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodesAfterSelf().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling nodes after this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> NodesAfterSelf(this XmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return NodesAfterSelfImpl(node);
+ }
+
+ private static IEnumerable<XmlNode> NodesAfterSelfImpl(XmlNode
node)
+ {
+ while ((node = node.NextSibling) != null)
+ yield return node;
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling elements before this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> ElementsBeforeSelf(this XmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodesBeforeSelf().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling nodes before this node.
+ /// </summary>
+ public static IEnumerable<XmlNode> NodesBeforeSelf(this XmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return NodesBeforeSelfImpl(node);
+ }
+
+ private static IEnumerable<XmlNode> NodesBeforeSelfImpl(XmlNode
node)
+ {
+ while ((node = node.PreviousSibling) != null)
+ yield return node;
+ }
+
+ /// <summary>
+ /// Returns a collection of all descendant nodes of this element.
+ /// </summary>
+ public static IEnumerable<XmlNode> Descendants(this XmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return DescendantsImpl(node);
+ }
+
+ private static IEnumerable<XmlNode> DescendantsImpl(XmlNode node)
+ {
+ Debug.Assert(node != null);
+ foreach (XmlNode child in node.ChildNodes)
+ {
+ yield return child;
+ foreach (var descendant in child.Descendants())
+ yield return descendant;
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/Xml/XmlNodeOps.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,230 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.XmlNodeQuery
+{
+ #region Imports
+
+ using System;
+ using System.Linq;
+ using System.Xml;
+
+ #endregion
+
+ public class XmlNodeOps : IElementOps<XmlNode>
+ {
+ public virtual Selector<XmlNode> Type(NamespacePrefix prefix,
string type)
+ {
+ // TODO Proper namespace support
+ return nodes => nodes.Where(n => n.Name == type);
+ }
+
+ public virtual Selector<XmlNode> Universal(NamespacePrefix prefix)
+ {
+ // TODO Proper namespace support
+ return nodes => nodes.Elements();
+ }
+
+ public virtual Selector<XmlNode> Id(string id)
+ {
+ return AttributeExact(NamespacePrefix.None, "id", id);
+ }
+
+ public virtual Selector<XmlNode> Class(string clazz)
+ {
+ return AttributeIncludes(NamespacePrefix.None, "class", clazz);
+ }
+
+ public virtual Selector<XmlNode> AttributeExists(NamespacePrefix
prefix, string name)
+ {
+ // TODO Proper namespace support
+ return nodes => nodes.Elements().Where(n =>
n.Attributes[name] != null);
+ }
+
+ public virtual Selector<XmlNode> AttributeExact(NamespacePrefix
prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value == value
+ select n;
+ }
+
+ public virtual Selector<XmlNode> AttributeIncludes(NamespacePrefix
prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split(' ').Contains(value)
+ select n;
+ }
+
+ public virtual Selector<XmlNode>
AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return string.IsNullOrEmpty(value)
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split('-').Contains(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributePrefixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return string.IsNullOrEmpty(value)
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.StartsWith(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributeSuffixMatch(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return string.IsNullOrEmpty(value)
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.EndsWith(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode>
AttributeSubstring(NamespacePrefix prefix, string name, string value)
+ {
+ // TODO Proper namespace support
+ return string.IsNullOrEmpty(value)
+ ? (Selector<XmlNode>)(nodes =>
Enumerable.Empty<XmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.Contains(value)
+ select n);
+ }
+
+ public virtual Selector<XmlNode> FirstChild()
+ {
+ return nodes => nodes.Where(n
=> !n.ElementsBeforeSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the last child of some
other element.
+ /// </summary>
+ public virtual Selector<XmlNode> LastChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
+ && !n.ElementsAfterSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child of some
other element.
+ /// </summary>
+ public virtual Selector<XmlNode> NthChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-child(an+b)
selector where a is not 1 is not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Take(b).ToArray()
+ where elements.Length == b &&
elements.Last().Equals(n)
+ select n;
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has a parent element and
whose parent
+ /// element has no other element children.
+ /// </summary>
+ public virtual Selector<XmlNode> OnlyChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
XmlNodeType.Document
+
&& !n.ElementsAfterSelf().Concat(n.ElementsBeforeSelf()).Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has no children at all.
+ /// </summary>
+ public virtual Selector<XmlNode> Empty()
+ {
+ return nodes => nodes.Elements().Where(n => n.ChildNodes.Count
== 0);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a childhood relationship between two elements.
+ /// </summary>
+ public virtual Selector<XmlNode> Child()
+ {
+ return nodes => nodes.SelectMany(n => n.Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a relationship between two elements where one
element is an
+ /// arbitrary descendant of some ancestor element.
+ /// </summary>
+ public virtual Selector<XmlNode> Descendant()
+ {
+ return nodes => nodes.SelectMany(n =>
n.Descendants().Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents elements that share the same parent in the
document tree and
+ /// where the first element immediately precedes the second
element.
+ /// </summary>
+ public virtual Selector<XmlNode> Adjacent()
+ {
+ return nodes => nodes.SelectMany(n =>
n.ElementsAfterSelf().Take(1));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<XmlNode> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ public Selector<XmlNode> NthLastChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-last-child(an+b)
selector where a is not 1 is not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Skip(Math.Max(0, n.ParentNode.Elements().Count() -
b)).Take(b).ToArray()
+ where elements.Length == b &&
elements.First().Equals(n)
+ select n;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Sandbox/Xml/XmlNodeSelection.cs Wed Oct 15 05:52:25 2014
UTC
@@ -0,0 +1,55 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.XmlNodeQuery
+{
+ #region Imports
+
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Xml;
+
+ #endregion
+
+ public static class XmlNodeSelection
+ {
+ /// <summary>
+ /// Similar to <see cref="QuerySelectorAll" /> except it returns
+ /// only the first element matching the supplied selector strings.
+ /// </summary>
+ public static XmlNode QuerySelector(this XmlNode node, string
selector)
+ {
+ return node.QuerySelectorAll(selector).FirstOrDefault();
+ }
+
+ /// <summary>
+ /// Retrieves all element nodes from descendants of the starting
+ /// element node that match any selector within the supplied
+ /// selector strings.
+ /// </summary>
+ public static IEnumerable<XmlNode> QuerySelectorAll(this XmlNode
node, string selector)
+ {
+ var generator = new SelectorGenerator<XmlNode>(new
XmlNodeOps());
+ Parser.Parse(selector, generator);
+ return generator.Selector(Enumerable.Repeat(node, 1));
+ }
+ }
+}
=======================================
--- /dev/null
+++
/src/Fizzler.Systems.HtmlAgilityPack/Fizzler.Systems.HtmlAgilityPack.csproj
Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)'
== '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{DBEAD205-BD5C-461F-873D-DE643016F14C}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Fizzler.Systems.HtmlAgilityPack</RootNamespace>
+ <AssemblyName>Fizzler.Systems.HtmlAgilityPack</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir)
== '*Undefined*'">..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|
AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <NoWarn>3001,3002</NoWarn>
+
<DocumentationFile>..\bin\Debug\Fizzler.Systems.HtmlAgilityPack.xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|
AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <NoWarn>3001,3002</NoWarn>
+
<DocumentationFile>..\bin\Release\Fizzler.Systems.HtmlAgilityPack.xml</DocumentationFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="HtmlAgilityPack, Version=1.4.6.0, Culture=neutral,
PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+
<HintPath>..\..\packages\HtmlAgilityPack.1.4.6\lib\Net20\HtmlAgilityPack.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.XML" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Common\SolutionInfo.cs">
+ <Link>SolutionInfo.cs</Link>
+ </Compile>
+ <Compile Include="HtmlDocumentExtensions.cs" />
+ <Compile Include="HtmlNodeExtensions.cs" />
+ <Compile Include="HtmlNodeOps.cs" />
+ <Compile Include="HtmlNodeSelection.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Fizzler\Fizzler.csproj">
+ <Project>{939036D6-29FD-46E4-B6CD-52618F51081B}</Project>
+ <Name>Fizzler</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+ <!-- To modify your build process, add your task inside one of the
targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/HtmlDocumentExtensions.cs Wed Oct
15 05:52:25 2014 UTC
@@ -0,0 +1,168 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.HtmlAgilityPack
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Runtime.CompilerServices;
+ using global::HtmlAgilityPack;
+
+ #endregion
+
+ /// <summary>
+ /// Extensions methods for <see cref="HtmlDocument"/>.
+ /// </summary>
+
+ public static class HtmlDocumentExtensions
+ {
+ private static Dictionary<string, HtmlElementFlag>
_defaultElementFlags;
+
+ /// <summary>
+ /// Same as <see cref="HtmlDocument.LoadHtml" /> but without the
FORM nesting
+ /// problem outlined in <a
href="
http://code.google.com/p/fizzler/issues/detail?id=24">issue #24</a>.
+ /// </summary>
+ /// <remarks>
+ /// This method is designed to be used by the Fizzler project tools
+ /// exclusively and may be removed from a future version.
+ /// </remarks>
+
+ public static void LoadHtml2(this HtmlDocument document, string
html)
+ {
+ if (document == null) throw new
ArgumentNullException("document");
+ document.LoadHtmlWithElementFlags(html, DefaultElementFlags);
+ }
+
+ /// <summary>
+ /// Same as <see cref="HtmlDocument.Load(string)" /> but without
the FORM nesting
+ /// problem outlined in <a
href="
http://code.google.com/p/fizzler/issues/detail?id=24">issue #24</a>.
+ /// </summary>
+ /// <remarks>
+ /// This method is designed to be used by the Fizzler project tools
+ /// exclusively and may be removed from a future version.
+ /// </remarks>
+
+ public static void Load2(this HtmlDocument document, string path)
+ {
+ if (document == null) throw new
ArgumentNullException("document");
+ document.LoadWithElementFlags(path, DefaultElementFlags);
+ }
+
+ /// <summary>
+ /// Parses the HTML and loads the document model using supplied
+ /// per-element handling options.
+ /// </summary>
+ /// <remarks>
+ /// The behavior of this method is not guaranteed to be thread-safe
+ /// and is primarily a hack around <see
cref="HtmlNode.ElementsFlags"/>
+ /// being static.
+ /// </remarks>
+ /// <remarks>
+ /// This method is designed to be used by the Fizzler project tools
+ /// exclusively and may be removed from a future version.
+ /// </remarks>
+
+ [MethodImpl(MethodImplOptions.Synchronized)]
+ public static void LoadHtmlWithElementFlags(this HtmlDocument
document, string html, IEnumerable<KeyValuePair<string, HtmlElementFlag>>
flags)
+ {
+ if (document == null) throw new
ArgumentNullException("document");
+ LoadWithElementFlags(flags, () => document.LoadHtml(html));
+ }
+
+ /// <summary>
+ /// Parses the HTML and loads the document model using supplied
+ /// per-element handling options.
+ /// </summary>
+ /// <remarks>
+ /// The behavior of this method is not guaranteed to be thread-safe
+ /// and is primarily a hack around <see
cref="HtmlNode.ElementsFlags"/>
+ /// being static.
+ /// </remarks>
+ /// <remarks>
+ /// This method is designed to be used by the Fizzler project tools
+ /// exclusively and may be removed from a future version.
+ /// </remarks>
+
+ [MethodImpl(MethodImplOptions.Synchronized)]
+ public static void LoadWithElementFlags(this HtmlDocument
document, string path, IEnumerable<KeyValuePair<string, HtmlElementFlag>>
flags)
+ {
+ if (document == null) throw new
ArgumentNullException("document");
+ LoadWithElementFlags(flags, () => document.Load(path));
+ }
+
+ private delegate void LoadHandler();
+
+ private static void
LoadWithElementFlags(IEnumerable<KeyValuePair<string, HtmlElementFlag>>
flags, LoadHandler loader)
+ {
+ Dictionary<string, HtmlElementFlag> oldFlags = null;
+ try
+ {
+ if (flags != null)
+ {
+ oldFlags = HtmlNode.ElementsFlags.Clone();
+ HtmlNode.ElementsFlags.Reload(flags);
+ }
+ loader();
+ }
+ finally
+ {
+ if (oldFlags != null)
+ HtmlNode.ElementsFlags.Reload(oldFlags);
+ }
+ }
+
+ private static Dictionary<TKey, TValue> Clone<TKey, TValue>(this
Dictionary<TKey, TValue> source)
+ {
+ Debug.Assert(source != null);
+ return new Dictionary<TKey, TValue>(source, source.Comparer);
+ }
+
+ private static void Reload<TKey, TValue>(this IDictionary<TKey,
TValue> target, IEnumerable<KeyValuePair<TKey, TValue>> source)
+ {
+ Debug.Assert(source != null);
+ Debug.Assert(target != null);
+
+ target.Clear();
+ foreach (var entry in source)
+ target[entry.Key] = entry.Value;
+ }
+
+ private static Dictionary<string, HtmlElementFlag>
DefaultElementFlags
+ {
+ get
+ {
+ if (_defaultElementFlags == null)
+ {
+ var flags = HtmlNode.ElementsFlags.Clone();
+ // ReSharper disable BitwiseOperatorOnEnumWihtoutFlags
+ flags["form"] = flags["form"] | HtmlElementFlag.Closed;
+ // ReSharper restore BitwiseOperatorOnEnumWihtoutFlags
+ _defaultElementFlags = flags;
+ }
+
+ return _defaultElementFlags;
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeExtensions.cs Wed Oct 15
05:52:25 2014 UTC
@@ -0,0 +1,179 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.HtmlAgilityPack
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Text;
+ using global::HtmlAgilityPack;
+
+ #endregion
+
+ /// <summary>
+ /// HtmlNode extension methods.
+ /// </summary>
+ public static class HtmlNodeExtensions
+ {
+ /// <summary>
+ /// Determines whether this node is an element or not.
+ /// </summary>
+ public static bool IsElement(this HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodeType == HtmlNodeType.Element;
+ }
+
+ /// <summary>
+ /// Returns a collection of elements from this collection.
+ /// </summary>
+ public static IEnumerable<HtmlNode> Elements(this
IEnumerable<HtmlNode> nodes)
+ {
+ if (nodes == null) throw new ArgumentNullException("nodes");
+ return nodes.Where(n => n.IsElement());
+ }
+
+ /// <summary>
+ /// Returns a collection of child nodes of this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> Children(this HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.ChildNodes.Cast<HtmlNode>();
+ }
+
+ /// <summary>
+ /// Returns a collection of child elements of this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> Elements(this HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.Children().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling elements after this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> ElementsAfterSelf(this
HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodesAfterSelf().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling nodes after this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> NodesAfterSelf(this HtmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return NodesAfterSelfImpl(node);
+ }
+
+ private static IEnumerable<HtmlNode> NodesAfterSelfImpl(HtmlNode
node)
+ {
+ while ((node = node.NextSibling) != null)
+ yield return node;
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling elements before this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> ElementsBeforeSelf(this
HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return node.NodesBeforeSelf().Elements();
+ }
+
+ /// <summary>
+ /// Returns a collection of the sibling nodes before this node.
+ /// </summary>
+ public static IEnumerable<HtmlNode> NodesBeforeSelf(this HtmlNode
node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return NodesBeforeSelfImpl(node);
+ }
+
+ private static IEnumerable<HtmlNode> NodesBeforeSelfImpl(HtmlNode
node)
+ {
+ while ((node = node.PreviousSibling) != null)
+ yield return node;
+ }
+
+ /// <summary>
+ /// Returns a collection of nodes that contains this element
+ /// followed by all descendant nodes of this element.
+ /// </summary>
+ public static IEnumerable<HtmlNode> DescendantsAndSelf(this
HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return Enumerable.Repeat(node, 1).Concat(node.Descendants());
+ }
+
+ /// <summary>
+ /// Returns a collection of all descendant nodes of this element.
+ /// </summary>
+ public static IEnumerable<HtmlNode> Descendants(this HtmlNode node)
+ {
+ if (node == null) throw new ArgumentNullException("node");
+ return DescendantsImpl(node);
+ }
+
+ private static IEnumerable<HtmlNode> DescendantsImpl(HtmlNode node)
+ {
+ Debug.Assert(node != null);
+ foreach (var child in node.ChildNodes)
+ {
+ yield return child;
+ foreach (var descendant in child.Descendants())
+ yield return descendant;
+ }
+ }
+
+ /// <summary>
+ /// Returns a begin tag, including attributes, string
+ /// representation of this element.
+ /// </summary>
+ public static string GetBeginTagString(this HtmlNode node)
+ {
+ if(node == null) throw new ArgumentNullException("node");
+
+ if (!node.IsElement())
+ return string.Empty;
+
+ var sb = new StringBuilder().Append('<').Append(node.Name);
+
+ foreach (var attribute in node.Attributes)
+ {
+ sb.Append(' ')
+ .Append(attribute.Name)
+ .Append("=\"")
+ .Append(HtmlDocument.HtmlEncode(attribute.Value))
+ .Append('\"');
+ }
+
+ return sb.Append('>').ToString();
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeOps.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,298 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.HtmlAgilityPack
+{
+ #region Imports
+
+ using System;
+ using System.Linq;
+ using global::HtmlAgilityPack;
+
+ #endregion
+
+ /// <summary>
+ /// An <see cref="IElementOps{TElement}"/> implementation for <see
cref="HtmlNode"/>
+ /// from <a
href="
http://www.codeplex.com/htmlagilitypack">HtmlAgilityPack</a>.
+ /// </summary>
+ public class HtmlNodeOps : IElementOps<HtmlNode>
+ {
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#type-selectors">type
selector</a>,
+ /// which represents an instance of the element type in the
document tree.
+ /// </summary>
+ public virtual Selector<HtmlNode> Type(NamespacePrefix prefix,
string type)
+ {
+ return prefix.IsSpecific
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => nodes.Elements().Where(n => n.Name == type));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#universal-selector">universal
selector</a>,
+ /// any single element in the document tree in any namespace
+ /// (including those without a namespace) if no default namespace
+ /// has been specified for selectors.
+ /// </summary>
+ public virtual Selector<HtmlNode> Universal(NamespacePrefix prefix)
+ {
+ return prefix.IsSpecific
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => nodes.Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#Id-selectors">ID selector</a>,
+ /// which represents an element instance that has an identifier
that
+ /// matches the identifier in the ID selector.
+ /// </summary>
+ public virtual Selector<HtmlNode> Id(string id)
+ {
+ return nodes => nodes.Elements().Where(n => n.Id == id);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#class-html">class selector</a>,
+ /// which is an alternative <see
cref="IElementOps{TElement}.AttributeIncludes"/> when
+ /// representing the <c>class</c> attribute.
+ /// </summary>
+ public virtual Selector<HtmlNode> Class(string clazz)
+ {
+ return nodes => nodes.Elements().Where(n =>
n.GetAttributeValue("class", string.Empty)
+ .Split(' ')
+ .Contains(clazz));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the given attribute <paramref
name="name"/>
+ /// whatever the values of the attribute.
+ /// </summary>
+ public virtual Selector<HtmlNode> AttributeExists(NamespacePrefix
prefix, string name)
+ {
+ return prefix.IsSpecific
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => nodes.Elements().Where(n =>
n.Attributes[name] != null));
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the given attribute <paramref
name="name"/>
+ /// and whose value is exactly <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<HtmlNode> AttributeExact(NamespacePrefix
prefix, string name, string value)
+ {
+ return prefix.IsSpecific
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value == value
+ select n);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the given attribute <paramref
name="name"/>
+ /// and whose value is a whitespace-separated list of words, one of
+ /// which is exactly <paramref name="value"/>.
+ /// </summary>
+ public virtual Selector<HtmlNode>
AttributeIncludes(NamespacePrefix prefix, string name, string value)
+ {
+ return prefix.IsSpecific
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split(' ').Contains(value)
+ select n);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the given attribute <paramref
name="name"/>,
+ /// its value either being exactly <paramref name="value"/> or
beginning
+ /// with <paramref name="value"/> immediately followed by "-"
(U+002D).
+ /// </summary>
+ public virtual Selector<HtmlNode>
AttributeDashMatch(NamespacePrefix prefix, string name, string value)
+ {
+ return prefix.IsSpecific || string.IsNullOrEmpty(value)
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null &&
a.Value.Split('-').Contains(value)
+ select n);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the attribute <paramref
name="name"/>
+ /// whose value begins with the prefix <paramref name="value"/>.
+ /// </summary>
+ public Selector<HtmlNode> AttributePrefixMatch(NamespacePrefix
prefix, string name, string value)
+ {
+ return prefix.IsSpecific || string.IsNullOrEmpty(value)
+ ? (Selector<HtmlNode>) (nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.StartsWith(value)
+ select n);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the attribute <paramref
name="name"/>
+ /// whose value ends with the suffix <paramref name="value"/>.
+ /// </summary>
+ public Selector<HtmlNode> AttributeSuffixMatch(NamespacePrefix
prefix, string name, string value)
+ {
+ return prefix.IsSpecific || string.IsNullOrEmpty(value)
+ ? (Selector<HtmlNode>)(nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.EndsWith(value)
+ select n);
+ }
+
+ /// <summary>
+ /// Generates an <a
href="
http://www.w3.org/TR/css3-selectors/#attribute-selectors">attribute
selector</a>
+ /// that represents an element with the attribute <paramref
name="name"/>
+ /// whose value contains at least one instance of the substring
<paramref name="value"/>.
+ /// </summary>
+ public Selector<HtmlNode> AttributeSubstring(NamespacePrefix
prefix, string name, string value)
+ {
+ return prefix.IsSpecific || string.IsNullOrEmpty(value)
+ ? (Selector<HtmlNode>)(nodes =>
Enumerable.Empty<HtmlNode>())
+ : (nodes => from n in nodes.Elements()
+ let a = n.Attributes[name]
+ where a != null && a.Value.Contains(value)
+ select n);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the first child of some
other element.
+ /// </summary>
+ public virtual Selector<HtmlNode> FirstChild()
+ {
+ return nodes => nodes.Where(n
=> !n.ElementsBeforeSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the last child of some
other element.
+ /// </summary>
+ public virtual Selector<HtmlNode> LastChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
HtmlNodeType.Document
+ && !n.ElementsAfterSelf().Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child of some
other element.
+ /// </summary>
+ public virtual Selector<HtmlNode> NthChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-child(an+b)
selector where a is not 1 is not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Take(b).ToArray()
+ where elements.Length == b &&
elements.Last().Equals(n)
+ select n;
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has a parent element and
whose parent
+ /// element has no other element children.
+ /// </summary>
+ public virtual Selector<HtmlNode> OnlyChild()
+ {
+ return nodes => nodes.Where(n => n.ParentNode.NodeType !=
HtmlNodeType.Document
+
&& !n.ElementsAfterSelf().Concat(n.ElementsBeforeSelf()).Any());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that has no children at all.
+ /// </summary>
+ public virtual Selector<HtmlNode> Empty()
+ {
+ return nodes => nodes.Elements().Where(n => n.ChildNodes.Count
== 0);
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a childhood relationship between two elements.
+ /// </summary>
+ public virtual Selector<HtmlNode> Child()
+ {
+ return nodes => nodes.SelectMany(n => n.Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents a relationship between two elements where one
element is an
+ /// arbitrary descendant of some ancestor element.
+ /// </summary>
+ public virtual Selector<HtmlNode> Descendant()
+ {
+ return nodes => nodes.SelectMany(n =>
n.Descendants().Elements());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which represents elements that share the same parent in the
document tree and
+ /// where the first element immediately precedes the second
element.
+ /// </summary>
+ public virtual Selector<HtmlNode> Adjacent()
+ {
+ return nodes => nodes.SelectMany(n =>
n.ElementsAfterSelf().Take(1));
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#combinators">combinator</a>,
+ /// which separates two sequences of simple selectors. The
elements represented
+ /// by the two sequences share the same parent in the document
tree and the
+ /// element represented by the first sequence precedes (not
necessarily
+ /// immediately) the element represented by the second one.
+ /// </summary>
+ public virtual Selector<HtmlNode> GeneralSibling()
+ {
+ return nodes => nodes.SelectMany(n => n.ElementsAfterSelf());
+ }
+
+ /// <summary>
+ /// Generates a <a
href="
http://www.w3.org/TR/css3-selectors/#pseudo-classes">pseudo-class
selector</a>,
+ /// which represents an element that is the N-th child from bottom
up of some other element.
+ /// </summary>
+ public Selector<HtmlNode> NthLastChild(int a, int b)
+ {
+ if (a != 1)
+ throw new NotSupportedException("The nth-last-child(an+b)
selector where a is not 1 is not supported.");
+
+ return nodes => from n in nodes
+ let elements =
n.ParentNode.Elements().Skip(Math.Max(0, n.ParentNode.Elements().Count() -
b)).Take(b).ToArray()
+ where elements.Length == b &&
elements.First().Equals(n)
+ select n;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/HtmlNodeSelection.cs Wed Oct 15
05:52:25 2014 UTC
@@ -0,0 +1,140 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Systems.HtmlAgilityPack
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using global::HtmlAgilityPack;
+
+ #endregion
+
+ /// <summary>
+ /// Selector API for <see cref="HtmlNode"/>.
+ /// </summary>
+ /// <remarks>
+ /// For more information, see <a
href="
http://www.w3.org/TR/selectors-api/">Selectors API</a>.
+ /// </remarks>
+ public static class HtmlNodeSelection
+ {
+ private static readonly HtmlNodeOps _ops = new HtmlNodeOps();
+
+ /// <summary>
+ /// Similar to <see cref="QuerySelectorAll(HtmlNode,string)" />
+ /// except it returns only the first element matching the supplied
+ /// selector strings.
+ /// </summary>
+ public static HtmlNode QuerySelector(this HtmlNode node, string
selector)
+ {
+ return node.QuerySelectorAll(selector).FirstOrDefault();
+ }
+
+ /// <summary>
+ /// Retrieves all element nodes from descendants of the starting
+ /// element node that match any selector within the supplied
+ /// selector strings.
+ /// </summary>
+ public static IEnumerable<HtmlNode> QuerySelectorAll(this HtmlNode
node, string selector)
+ {
+ return QuerySelectorAll(node, selector, null);
+ }
+
+ /// <summary>
+ /// Retrieves all element nodes from descendants of the starting
+ /// element node that match any selector within the supplied
+ /// selector strings. An additional parameter specifies a
+ /// particular compiler to use for parsing and compiling the
+ /// selector.
+ /// </summary>
+ /// <remarks>
+ /// The <paramref name="compiler"/> can be <c>null</c>, in which
+ /// case a default compiler is used. If the selector is to be used
+ /// often, it is recommended to use a caching compiler such as the
+ /// one supplied by <see cref="CreateCachingCompiler()"/>.
+ /// </remarks>
+ public static IEnumerable<HtmlNode> QuerySelectorAll(this HtmlNode
node, string selector, Func<string, Func<HtmlNode, IEnumerable<HtmlNode>>>
compiler)
+ {
+ return (compiler ?? Compile)(selector)(node);
+ }
+
+ /// <summary>
+ /// Parses and compiles CSS selector text into run-time function.
+ /// </summary>
+ /// <remarks>
+ /// Use this method to compile and reuse frequently used CSS
selectors
+ /// without parsing them each time.
+ /// </remarks>
+ public static Func<HtmlNode, IEnumerable<HtmlNode>> Compile(string
selector)
+ {
+ var compiled = Parser.Parse(selector, new
SelectorGenerator<HtmlNode>(_ops)).Selector;
+ return node => compiled(Enumerable.Repeat(node, 1));
+ }
+
+ //
+ // Caching
+ //
+
+ [ThreadStatic]
+ private static readonly Func<string, Func<HtmlNode,
IEnumerable<HtmlNode>>> _defaultCachingCompiler = CreateCachingCompiler();
+
+ /// <summary>
+ /// Compiles a selector. If the selector has been previously
+ /// compiled then this method returns it rather than parsing
+ /// and compiling the selector on each invocation.
+ /// </summary>
+ /// <remarks>
+ /// The cache is per-thread and therefore thread-safe without
+ /// lock contention.
+ /// </remarks>
+ public static Func<HtmlNode, IEnumerable<HtmlNode>>
CachableCompile(string selector)
+ {
+ return _defaultCachingCompiler(selector);
+ }
+
+ /// <summary>
+ /// Creates a caching selector compiler that uses a default
+ /// cache strategy when the selector text is regarded as being
+ /// orginally case-insensitive.
+ /// </summary>
+ public static Func<string, Func<HtmlNode, IEnumerable<HtmlNode>>>
CreateCachingCompiler()
+ {
+ return CreateCachingCompiler(null);
+ }
+
+ /// <summary>
+ /// Creates a caching selector compiler where the compiled
selectors
+ /// are maintained in a user-supplied <see
cref="IDictionary{TKey,TValue}"/>
+ /// instance.
+ /// </summary>
+ /// <remarks>
+ /// If <paramref name="cache"/> is <c>null</c> then this method
uses a
+ /// the <see cref="Dictionary{TKey,TValue}"/> implementation with
an
+ /// ordinally case-insensitive selectors text comparer.
+ /// </remarks>
+ public static Func<string, Func<HtmlNode, IEnumerable<HtmlNode>>>
CreateCachingCompiler(IDictionary<string, Func<HtmlNode,
IEnumerable<HtmlNode>>> cache)
+ {
+ return SelectorsCachingCompiler.Create(Compile, cache);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/Properties/AssemblyInfo.cs Wed Oct
15 05:52:25 2014 UTC
@@ -0,0 +1,31 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+using System.Reflection;
+
+[assembly: AssemblyTitle("Fizzler.System.HtmlAgilityPack")]
+[assembly: AssemblyDescription("Fizzler for HtmlAgilityPack")]
+
+//
+// Version information
+//
+
+[assembly: AssemblyFileVersion("1.0.15619.2054")]
=======================================
--- /dev/null
+++ /src/Fizzler.Systems.HtmlAgilityPack/packages.config Wed Oct 15
05:52:25 2014 UTC
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="HtmlAgilityPack" version="1.4.6" targetFramework="net35" />
+</packages>
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/App.config Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="nunit.framework"
publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
+ <bindingRedirect oldVersion="2.4.8.0" newVersion="2.2.8.0"
/>
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/AttributeSelectors.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,152 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class AttributeSelectors : SelectorBaseTest
+ {
+ [Test]
+ public void Element_Attr_Exists()
+ {
+ var results = SelectList("div[id]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("div", results[1].Name);
+ }
+
+ [Test]
+ public void Element_Attr_Equals_With_Double_Quotes()
+ {
+ var results = SelectList("div[id=\"someOtherDiv\"]");
+
+ Assert.AreEqual(1, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ }
+
+ [Test]
+ public void Element_Attr_Space_Separated_With_Double_Quotes()
+ {
+ var results = SelectList("p[class~=\"ohyeah\"]");
+
+ Assert.AreEqual(1, results.Count);
+ Assert.AreEqual("p", results[0].Name);
+ Assert.AreEqual("eeeee", results[0].InnerText);
+ }
+
+ [Test]
+ public void Element_Attr_Space_Separated_With_Empty_Value()
+ {
+ Assert.AreEqual(0, SelectList("p[class~='']").Count);
+ }
+
+ [Test]
+ public void Element_Attr_Hyphen_Separated_With_Double_Quotes()
+ {
+ var results = SelectList("span[class|=\"separated\"]");
+
+ Assert.AreEqual(1, results.Count);
+ Assert.AreEqual("span", results[0].Name);
+ Assert.AreEqual("test", results[0].InnerText);
+ }
+
+ [Test]
+ public void Implicit_Star_Attr_Exact_With_Double_Quotes()
+ {
+ var results = SelectList("[class=\"checkit\"]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("woooeeeee", results[0].InnerText);
+ Assert.AreEqual("div", results[1].Name);
+ Assert.AreEqual("woootooowe", results[1].InnerText);
+ }
+
+ [Test]
+ public void Star_Attr_Exact_With_Double_Quotes()
+ {
+ var results = SelectList("*[class=\"checkit\"]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("woooeeeee", results[0].InnerText);
+ Assert.AreEqual("div", results[1].Name);
+ Assert.AreEqual("woootooowe", results[1].InnerText);
+ }
+
+ [Test]
+ public void Star_Attr_Prefix()
+ {
+ var results = SelectList("*[class^=check]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("woooeeeee", results[0].InnerText);
+ Assert.AreEqual("div", results[1].Name);
+ Assert.AreEqual("woootooowe", results[1].InnerText);
+ }
+
+ [Test]
+ public void Star_Attr_Prefix_With_Empty_Value()
+ {
+ Assert.AreEqual(0, SelectList("*[class^='']").Count);
+ }
+
+ [Test]
+ public void Star_Attr_Suffix()
+ {
+ var results = SelectList("*[class$=it]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("woooeeeee", results[0].InnerText);
+ Assert.AreEqual("div", results[1].Name);
+ Assert.AreEqual("woootooowe", results[1].InnerText);
+ }
+
+ [Test]
+ public void Star_Attr_Suffix_With_Empty_Value()
+ {
+ Assert.AreEqual(0, SelectList("*[class$='']").Count);
+ }
+
+ [Test]
+ public void Star_Attr_Substring()
+ {
+ var results = SelectList("*[class*=heck]");
+
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("div", results[0].Name);
+ Assert.AreEqual("woooeeeee", results[0].InnerText);
+ Assert.AreEqual("div", results[1].Name);
+ Assert.AreEqual("woootooowe", results[1].InnerText);
+ }
+
+ [Test]
+ public void Star_Attr_Substring_With_Empty_Value()
+ {
+ Assert.AreEqual(0, SelectList("*[class*='']").Count);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/ChildAndAdjacentSelectors.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,111 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class ChildAndAdjacentSelectors : SelectorBaseTest
+ {
+ [Test]
+ public void Child_With_Pre_And_Post_Space()
+ {
+ Assert.AreEqual(2, SelectList("div > p").Count);
+ }
+
+ [Test]
+ public void Child_With_Post_Space()
+ {
+ Assert.AreEqual(2, SelectList("div> p").Count);
+ }
+
+ [Test]
+ public void Child_With_Pre_Space()
+ {
+ Assert.AreEqual(2, SelectList("div >p").Count);
+ }
+
+ [Test]
+ public void Child_With_No_Space()
+ {
+ Assert.AreEqual(2, SelectList("div>p").Count);
+ }
+
+ [Test]
+ public void Child_With_Class()
+ {
+ Assert.AreEqual(1, SelectList("div > p.ohyeah").Count);
+ }
+
+ [Test]
+ public void All_Children()
+ {
+ // match <a href="">hi</a><span>test</span> so that's 3
+ Assert.AreEqual(3, SelectList("p > *").Count);
+ }
+
+ [Test]
+ public void All_GrandChildren()
+ {
+ // match <a href="">hi</a><span>test</span> so that's 3
+ // *any* second level children under any div
+ Assert.AreEqual(3, SelectList("div > * > *").Count);
+ }
+
+ [Test]
+ public void Adjacent_With_Pre_And_Post_Space()
+ {
+ Assert.AreEqual(1, SelectList("a + span").Count);
+ }
+
+ [Test]
+ public void Adjacent_With_Post_Space()
+ {
+ Assert.AreEqual(1, SelectList("a+ span").Count);
+ }
+
+ [Test]
+ public void Adjacent_With_Pre_Space()
+ {
+ Assert.AreEqual(1, SelectList("a +span").Count);
+ }
+
+ [Test]
+ public void Adjacent_With_No_Space()
+ {
+ Assert.AreEqual(1, SelectList("a+span").Count);
+ }
+
+ [Test]
+ public void Comma_Child_And_Adjacent()
+ {
+ Assert.AreEqual(3, SelectList("a + span, div > p").Count);
+ }
+
+ [Test]
+ public void General_Sibling_Combinator()
+ {
+ Assert.AreEqual(1, SelectList("div ~ form").Count);
+ Assert.AreEqual("form", SelectList("div ~ form")[0].Name);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/ClassSelector.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,72 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class ClassSelector : SelectorBaseTest
+ {
+ [Test]
+ public void Basic()
+ {
+ var result = SelectList(".checkit");
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ Assert.AreEqual("div", result[1].Name);
+ }
+
+ /// <summary>
+ /// Should match class="omg ohyeah"
+ /// </summary>
+ [Test]
+ public void Chained()
+ {
+ var result = SelectList(".omg.ohyeah");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("eeeee", result[0].InnerText);
+ }
+
+ [Test]
+ public void With_Element()
+ {
+ var result = SelectList("p.ohyeah");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("eeeee", result[0].InnerText);
+ }
+
+ [Test]
+ public void Parent_Class_Selector()
+ {
+ var result = SelectList("div .ohyeah");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("eeeee", result[0].InnerText);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/ElementSelector.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,98 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using System;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class ElementSelector : SelectorBaseTest
+ {
+ [Test]
+ public void Star()
+ {
+ Assert.AreEqual(16, SelectList("*").Count);
+ }
+
+ [Test]
+ public void Single_Tag_Name()
+ {
+ Assert.AreEqual(1, SelectList("body").Count);
+ Assert.AreEqual("body", SelectList("body")[0].Name);
+ }
+
+ [Test]
+ public void Single_Tag_Name_Matching_Multiple_Elements()
+ {
+ Assert.AreEqual(3, SelectList("p").Count);
+ Assert.AreEqual("p", SelectList("p")[0].Name);
+ Assert.AreEqual("p", SelectList("p")[1].Name);
+ Assert.AreEqual("p", SelectList("p")[2].Name);
+ }
+
+ [Test]
+ public void Basic_Negative_Precedence()
+ {
+ Assert.AreEqual(0, SelectList("head p").Count);
+ }
+
+ [Test]
+ public void Basic_Positive_Precedence_Two_Tags()
+ {
+ Assert.AreEqual(2, SelectList("div p").Count);
+ }
+
+ [Test]
+ public void
Basic_Positive_Precedence_Two_Tags_With_Grandchild_Descendant()
+ {
+ Assert.AreEqual(2, SelectList("div a").Count);
+ }
+
+ [Test]
+ public void Basic_Positive_Precedence_Three_Tags()
+ {
+ Assert.AreEqual(1, SelectList("div p a").Count);
+ Assert.AreEqual("a", SelectList("div p a")[0].Name);
+ }
+
+ [Test]
+ public void Basic_Positive_Precedence_With_Same_Tags()
+ {
+ Assert.AreEqual(1, SelectList("div div").Count);
+ }
+
+ /// <summary>
+ /// This test covers an issue with HtmlAgilityPack where form
childnodes().length == 0.
+ /// </summary>
+ [Test]
+ public void Basic_Positive_Precedence_Within_Form()
+ {
+ Assert.AreEqual(1, SelectList("form input").Count);
+ }
+
+ [Test,ExpectedException(typeof(FormatException))]
+ public void Type_Star()
+ {
+ SelectList("a*");
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/Fizzler.Tests.csproj Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)'
== '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{61EDF5C0-1854-4867-AE8A-7A1216E116C9}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Fizzler.Tests</RootNamespace>
+ <AssemblyName>Fizzler.Tests</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir)
== '*Undefined*'">..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|
AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|
AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="HtmlAgilityPack, Version=1.4.6.0, Culture=neutral,
PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+
<HintPath>..\..\packages\HtmlAgilityPack.1.4.6\lib\Net20\HtmlAgilityPack.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework, Version=2.6.2.12296,
Culture=neutral, PublicKeyToken=96d09a1eb7f44a77,
processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+
<HintPath>..\..\packages\NUnit.2.6.2\lib\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.XML" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AttributeSelectors.cs" />
+ <Compile Include="ChildAndAdjacentSelectors.cs" />
+ <Compile Include="ClassSelector.cs" />
+ <Compile Include="NthLastChild.cs" />
+ <Compile Include="ParserTests.cs" />
+ <Compile Include="HumanReadableSelectorGeneratorTests.cs" />
+ <Compile Include="IDSelector.cs" />
+ <Compile Include="MultipleSelectors.cs" />
+ <Compile Include="NamespacePrefixTests.cs" />
+ <Compile Include="NthChild.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ElementSelector.cs" />
+ <Compile Include="PsuedoSelectors.cs" />
+ <Compile Include="ReaderTests.cs" />
+ <Compile Include="SelectorBaseTest.cs" />
+ <Compile Include="SelectorGeneratorTeeTests.cs" />
+ <Compile Include="TokenerTests.cs" />
+ <Compile Include="TokenTests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Fizzler.Sandbox\Fizzler.Sandbox.csproj">
+ <Project>{80456F6D-6853-4244-8E3D-F22ECA0980EC}</Project>
+ <Name>Fizzler.Sandbox</Name>
+ </ProjectReference>
+ <ProjectReference
Include="..\Fizzler.Systems.HtmlAgilityPack\Fizzler.Systems.HtmlAgilityPack.csproj">
+ <Project>{DBEAD205-BD5C-461F-873D-DE643016F14C}</Project>
+
<Name>Fizzler.Systems.HtmlAgilityPack %28Systems\Fizzler.Systems.HtmlAgilityPack%29</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Fizzler\Fizzler.csproj">
+ <Project>{939036D6-29FD-46E4-B6CD-52618F51081B}</Project>
+ <Name>Fizzler</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="SelectorTest.html" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+ <!-- To modify your build process, add your task inside one of the
targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/HumanReadableSelectorGeneratorTests.cs Wed Oct 15
05:52:25 2014 UTC
@@ -0,0 +1,173 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using System;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class HumanReadableSelectorGeneratorTests
+ {
+ public class TestHumanReadableSelectorGenerator :
HumanReadableSelectorGenerator
+ {
+ public new void Add(string selector)
+ {
+ base.Add(selector);
+ }
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void Null_Selector()
+ {
+ var generator = new TestHumanReadableSelectorGenerator();
+ generator.Add(null);
+ }
+
+ [Test]
+ public void All_Elements()
+ {
+ Run("*", "Take all elements and select them.");
+ }
+
+ [Test]
+ public void Tag()
+ {
+ Run("p", "Take all <p> elements and select them.");
+ }
+
+ [Test]
+ public void Descendant()
+ {
+ Run("p a", "Take all <p> elements, then take their descendants
which are <a> elements and select them.");
+ }
+
+ [Test]
+ public void Three_Levels_Of_Descendant()
+ {
+ Run("p a img", "Take all <p> elements, then take their
descendants which are <a> elements. With those, take only their descendants
which are <img> elements and select them.");
+ }
+
+ [Test]
+ public void Attribute()
+ {
+ Run("a[href]", "Take all <a> elements which have attribute
href defined and select them.");
+ }
+
+ [Test]
+ public void Adjacent()
+ {
+ Run("a + span", "Take all <a> elements, then take their
immediate siblings which are <span> elements and select them.");
+ }
+
+ [Test]
+ public void Id()
+ {
+ Run("#nodeId", "Take all elements with an ID of 'nodeId' and
select them.");
+ }
+
+ [Test]
+ public void SelectorGroup()
+ {
+ Run("a, span", "Take all <a> elements and select them.
Combined with previous, take all <span> elements and select them.");
+ }
+
+ [Test]
+ public void GeneralSibling()
+ {
+ Run("div ~ p", "Take all <div> elements, then take their
siblings which are <p> elements and select them.");
+ }
+
+ [Test]
+ public void Empty()
+ {
+ Run("*:empty", "Take all elements where the element is empty
and select them.");
+ }
+
+ [Test]
+ public void FirstChild()
+ {
+ Run("*:first-child", "Take all elements which are the first
child of their parent and select them.");
+ }
+
+ [Test]
+ public void Child()
+ {
+ Run("* > p", "Take all elements, then take their immediate
children which are <p> elements and select them.");
+ }
+
+ [Test] public void Class()
+ {
+ Run(".myclass", "Take all elements with a class of 'myclass'
and select them.");
+ }
+
+ [Test] public void LastChild()
+ {
+ Run("*:last-child", "Take all elements which are the last
child of their parent and select them.");
+ }
+
+ [Test]
+ public void NthChild()
+ {
+ Run("*:nth-child(2)", "Take all elements where the element has
1n+2-1 sibling before it and select them.");
+ }
+
+ [Test]
+ public void OnlyChild()
+ {
+ Run("*:only-child", "Take all elements where the element is
the only child and select them.");
+ }
+
+ [Test] public void AttributeDashMatch()
+ {
+ Run("*[lang|='en']", "Take all elements which have attribute
lang with a hyphen separated value matching 'en' and select them.");
+ }
+ [Test] public void AttributeExact()
+ {
+ Run("*[title='hithere']", "Take all elements which have
attribute title with a value of 'hithere' and select them.");
+ }
+ [Test] public void AttributeIncludes()
+ {
+ Run("*[title~='hithere']", "Take all elements which have
attribute title that includes the word 'hithere' and select them.");
+ }
+ [Test] public void AttributeSubstring()
+ {
+ Run("*[title*='hithere']", "Take all elements which have
attribute title whose value contains 'hithere' and select them.");
+ }
+ [Test] public void AttributeSuffixMatch()
+ {
+ Run("*[title$='hithere']", "Take all elements which have
attribute title whose value ends with 'hithere' and select them.");
+ }
+
+ [Test]
+ public void AttributePrefixMatch()
+ {
+ Run("*[title^='hithere']", "Take all elements which have
attribute title whose value begins with 'hithere' and select them.");
+ }
+
+ private static void Run(string selector, string message)
+ {
+ var generator = new HumanReadableSelectorGenerator();
+ Parser.Parse(selector, generator);
+ Assert.AreEqual(message, generator.Text);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/IDSelector.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,117 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class IDSelector : SelectorBaseTest
+ {
+ [Test]
+ public void Basic_Selector()
+ {
+ var result = SelectList("#myDiv");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ }
+
+ [Test]
+ public void With_Element()
+ {
+ var result = SelectList("div#myDiv");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ }
+
+ [Test]
+ public void With_Existing_ID_Descendant()
+ {
+ var result = SelectList("#theBody #myDiv");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ }
+
+ [Test]
+ public void With_Non_Existant_ID_Descendant()
+ {
+ var result = SelectList("#theBody #whatwhatwhat");
+
+ Assert.AreEqual(0, result.Count);
+ }
+
+ [Test]
+ public void With_Non_Existant_ID_Ancestor()
+ {
+ var result = SelectList("#whatwhatwhat #someOtherDiv");
+
+ Assert.AreEqual(0, result.Count);
+ }
+
+ [Test]
+ public void All_Descendants_Of_ID()
+ {
+ var result = SelectList("#myDiv *");
+
+ Assert.AreEqual(5, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ Assert.AreEqual("p", result[1].Name);
+ }
+
+ [Test]
+ public void Child_ID()
+ {
+ var result = SelectList("#theBody>#myDiv");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ }
+
+ [Test]
+ public void Not_A_Child_ID()
+ {
+ var result = SelectList("#theBody>#someOtherDiv");
+
+ Assert.AreEqual(0, result.Count);
+ }
+
+ [Test]
+ public void All_Children_Of_ID()
+ {
+ var result = SelectList("#myDiv>*");
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ Assert.AreEqual("p", result[1].Name);
+ }
+
+ [Test]
+ public void All_Children_of_ID_with_no_children()
+ {
+ var result = SelectList("#someOtherDiv>*");
+
+ Assert.AreEqual(0, result.Count);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/MultipleSelectors.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,69 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class MultipleSelectors : SelectorBaseTest
+ {
+ [Test]
+ public void CommaSupport_With_No_Space()
+ {
+ var result = SelectList("p.hiclass,a");
+
+ Assert.AreEqual(3, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("a", result[1].Name);
+ }
+
+ [Test]
+ public void CommaSupport_With_Post_Pended_Space()
+ {
+ var result = SelectList("p.hiclass, a");
+
+ Assert.AreEqual(3, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("a", result[1].Name);
+ }
+
+ [Test]
+ public void CommaSupport_With_Pre_Post_Pended_Space()
+ {
+ var result = SelectList("p.hiclass , a");
+
+ Assert.AreEqual(3, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("a", result[1].Name);
+ }
+
+ [Test]
+ public void CommaSupport_With_Pre_Pended_Space()
+ {
+ var result = SelectList("p.hiclass ,a");
+
+ Assert.AreEqual(3, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("a", result[1].Name);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/NamespacePrefixTests.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,215 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class NamespacePrefixTests
+ {
+ [Test]
+ public void Initialization()
+ {
+ Assert.That(new NamespacePrefix("foo").Text,
Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void NoneText()
+ {
+ Assert.That(NamespacePrefix.None.Text, Is.Null);
+ }
+
+ [Test]
+ public void NoneIsNone()
+ {
+ Assert.That(NamespacePrefix.None.IsNone, Is.True);
+ }
+
+ [Test]
+ public void NoneIsNotAny()
+ {
+ Assert.That(NamespacePrefix.None.IsAny, Is.False);
+ }
+
+ [Test]
+ public void NoneIsNotEmpty()
+ {
+ Assert.That(NamespacePrefix.None.IsEmpty, Is.False);
+ }
+
+ [Test]
+ public void NoneIsNotSpecific()
+ {
+ Assert.That(NamespacePrefix.None.IsSpecific, Is.False);
+ }
+
+ [Test]
+ public void AnyText()
+ {
+ Assert.That(NamespacePrefix.Any.Text, Is.EqualTo("*"));
+ }
+
+ [Test]
+ public void AnyIsNotNone()
+ {
+ Assert.That(NamespacePrefix.Any.IsNone, Is.False);
+ }
+
+ [Test]
+ public void AnyIsAny()
+ {
+ Assert.That(NamespacePrefix.Any.IsAny, Is.True);
+ }
+
+ [Test]
+ public void AnyIsNotEmpty()
+ {
+ Assert.That(NamespacePrefix.Any.IsEmpty, Is.False);
+ }
+
+ [Test]
+ public void AnyIsNotSpecific()
+ {
+ Assert.That(NamespacePrefix.Any.IsSpecific, Is.False);
+ }
+
+ [Test]
+ public void EmptyText()
+ {
+ Assert.That(NamespacePrefix.Empty.Text,
Is.EqualTo(string.Empty));
+ }
+
+ [Test]
+ public void EmptyIsNotNone()
+ {
+ Assert.That(NamespacePrefix.Empty.IsNone, Is.False);
+ }
+
+ [Test]
+ public void EmptyIsNotAny()
+ {
+ Assert.That(NamespacePrefix.Empty.IsAny, Is.False);
+ }
+
+ [Test]
+ public void EmptyIsEmpty()
+ {
+ Assert.That(NamespacePrefix.Empty.IsEmpty, Is.True);
+ }
+
+ [Test]
+ public void EmptyIsSpecific()
+ {
+ Assert.That(NamespacePrefix.Empty.IsSpecific, Is.True);
+ }
+
+ [Test]
+ public void Equality()
+ {
+ Assert.That(NamespacePrefix.None.Equals(NamespacePrefix.None),
Is.True);
+ Assert.That(NamespacePrefix.Any.Equals(NamespacePrefix.Any),
Is.True);
+
Assert.That(NamespacePrefix.Empty.Equals(NamespacePrefix.Empty), Is.True);
+ var foo = new NamespacePrefix("foo");
+ Assert.That(foo.Equals(foo), Is.True);
+ Assert.That(foo.Equals((object) foo), Is.True);
+ }
+
+ [Test]
+ public void Inequality()
+ {
+ var foo = new NamespacePrefix("foo");
+ var bar = new NamespacePrefix("bar");
+ Assert.That(foo.Equals(bar), Is.False);
+ Assert.That(foo.Equals((object)bar), Is.False);
+ }
+
+ [Test]
+ public void TypeEquality()
+ {
+ var foo = new NamespacePrefix("foo");
+ Assert.That(foo, Is.Not.EqualTo(null));
+ Assert.That(foo, Is.Not.EqualTo(123));
+ }
+
+ [Test]
+ public void NoneHashCode()
+ {
+ Assert.That(0, Is.EqualTo(NamespacePrefix.None.GetHashCode()));
+ }
+
+ [Test]
+ public void HashCode()
+ {
+ var foo = new NamespacePrefix("foo");
+ var bar = new NamespacePrefix("bar");
+ Assert.That(foo.GetHashCode() == bar.GetHashCode(), Is.False);
+ }
+
+ [Test]
+ public void NoneStringRepresentation()
+ {
+ Assert.That(NamespacePrefix.None.ToString(),
Is.EqualTo("(none)"));
+ }
+
+ [Test]
+ public void EmptyStringRepresentation()
+ {
+ Assert.That(NamespacePrefix.Empty.ToString(),
Is.EqualTo(string.Empty));
+ }
+
+ [Test]
+ public void AnyStringRepresentation()
+ {
+ Assert.That(NamespacePrefix.Any.ToString(), Is.EqualTo("*"));
+ }
+
+ [Test]
+ public void StringRepresentation()
+ {
+ Assert.That(new NamespacePrefix("foo").ToString(),
Is.EqualTo("foo"));
+ }
+
+ [Test]
+ public void FormatNone()
+ {
+ Assert.That(NamespacePrefix.None.Format("name"),
Is.EqualTo("name"));
+ }
+
+ [Test]
+ public void FormatAny()
+ {
+ Assert.That(NamespacePrefix.Any.Format("name"), Is.EqualTo("*|
name"));
+ }
+
+ [Test]
+ public void FormatEmpty()
+ {
+ Assert.That(NamespacePrefix.Empty.Format("name"), Is.EqualTo("|
name"));
+ }
+
+ [Test]
+ public void Format()
+ {
+ Assert.That(new NamespacePrefix("foo").Format("bar"),
Is.EqualTo("foo|bar"));
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/NthChild.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,66 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class NthChild : SelectorBaseTest
+ {
+ /// <summary>
+ /// Behaves the same as *:nth-child(2)
+ /// </summary>
+ [Test]
+ public void No_Prefix_With_Digit()
+ {
+ var result = SelectList(":nth-child(2)");
+
+ Assert.AreEqual(4, result.Count);
+ Assert.AreEqual("body", result[0].Name);
+ Assert.AreEqual("p", result[1].Name);
+ Assert.AreEqual("span", result[2].Name);
+ Assert.AreEqual("p", result[3].Name);
+ }
+
+ [Test]
+ public void Star_Prefix_With_Digit()
+ {
+ var result = SelectList("*:nth-child(2)");
+
+ Assert.AreEqual(4, result.Count);
+ Assert.AreEqual("body", result[0].Name);
+ Assert.AreEqual("p", result[1].Name);
+ Assert.AreEqual("span", result[2].Name);
+ Assert.AreEqual("p", result[3].Name);
+ }
+
+ [Test]
+ public void Element_Prefix_With_Digit()
+ {
+ var result = SelectList("p:nth-child(2)");
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual("p", result[0].Name);
+ Assert.AreEqual("p", result[1].Name);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/NthLastChild.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,48 @@
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class NthLastChild : SelectorBaseTest
+ {
+ [Test]
+ public void No_Prefix_With_Digit()
+ {
+ var result = SelectList(":nth-last-child(2)");
+
+ Assert.AreEqual(4, result.Count);
+ Assert.AreEqual("head", result[0].Name);
+ Assert.AreEqual("div", result[1].Name);
+ Assert.AreEqual("span", result[2].Name);
+ Assert.AreEqual("div", result[3].Name);
+ }
+
+ [Test]
+ public void Id_Prefix_With_Digit()
+ {
+ var result = SelectList("#myDiv :nth-last-child(2)");
+
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual("div", result[0].Name);
+ Assert.AreEqual("span", result[1].Name);
+ }
+
+ [Test]
+ public void Element_Prefix_With_Digit()
+ {
+ var result = SelectList("span:nth-last-child(3)");
+
+ Assert.AreEqual(0, result.Count);
+ }
+
+ [Test]
+ public void Element_Prefix_With_Digit2()
+ {
+ var result = SelectList("span:nth-last-child(2)");
+
+ Assert.AreEqual(1, result.Count);
+ Assert.AreEqual("span", result[0].Name);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/ParserTests.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,515 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using NUnit.Framework;
+
+ #endregion
+
+ [TestFixture]
+ public class ParserTests
+ {
+ [Test]
+ public void TypeNoNamespace()
+ {
+ Test("x", g => g.TypePrefix, NamespacePrefix.None,
+ g => g.TypeName, "x");
+ }
+
+ [Test]
+ public void TypeEmptyNamespace()
+ {
+ Test("|x", g => g.TypePrefix, NamespacePrefix.Empty,
+ g => g.TypeName, "x");
+ }
+
+ [Test]
+ public void TypeAnyNamespace()
+ {
+ Test("*|x", g => g.TypePrefix, NamespacePrefix.Any,
+ g => g.TypeName, "x");
+ }
+
+ [Test]
+ public void NamespacedType()
+ {
+ Test("foo|bar", g => g.TypePrefix, new NamespacePrefix("foo"),
+ g => g.TypeName, "bar");
+ }
+
+ [Test]
+ public void UniversalNoNamespace()
+ {
+ Test("*", g => g.UniversalPrefix, NamespacePrefix.None);
+ }
+
+ [Test]
+ public void UniversalEmptyNamespace()
+ {
+ Test("|*", g => g.UniversalPrefix, NamespacePrefix.Empty);
+ }
+
+ [Test]
+ public void UniversalAnyNamespace()
+ {
+ Test("*|*", g => g.UniversalPrefix, NamespacePrefix.Any);
+ }
+
+ [Test]
+ public void NamespacedUniversal()
+ {
+ Test("foo|*", g => g.UniversalPrefix, new
NamespacePrefix("foo"));
+ }
+
+ [Test]
+ public void NoNamespaceAttribueExists()
+ {
+ Test("[foo]", g => g.AttributeExistsPrefix,
NamespacePrefix.None,
+ g => g.AttributeExistsName, "foo");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueExists()
+ {
+ Test("[|a]", g => g.AttributeExistsPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeExistsName, "a");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueExists()
+ {
+ Test("[*|a]", g => g.AttributeExistsPrefix,
NamespacePrefix.Any,
+ g => g.AttributeExistsName, "a");
+ }
+
+ [Test]
+ public void NamespacedAttribueExists()
+ {
+ Test("[ns|a]", g => g.AttributeExistsPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeExistsName, "a");
+ }
+
+ [Test]
+ public void NoNamespaceAttribueExact()
+ {
+ Test("[a=v]", g => g.AttributeExactPrefix,
NamespacePrefix.None,
+ g => g.AttributeExactName, "a",
+ g => g.AttributeExactValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueExact()
+ {
+ Test("[|a=v]", g => g.AttributeExactPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeExactName, "a",
+ g => g.AttributeExactValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueExact()
+ {
+ Test("[*|a=v]", g => g.AttributeExactPrefix,
NamespacePrefix.Any,
+ g => g.AttributeExactName, "a",
+ g => g.AttributeExactValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribueExact()
+ {
+ Test("[ns|a=v]", g => g.AttributeExactPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeExactName, "a",
+ g => g.AttributeExactValue, "v");
+ }
+
+ [Test]
+ public void NoNamespaceAttribueIncludes()
+ {
+ Test("[a~=v]", g => g.AttributeIncludesPrefix,
NamespacePrefix.None,
+ g => g.AttributeIncludesName, "a",
+ g => g.AttributeIncludesValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueIncludes()
+ {
+ Test("[|a~=v]", g => g.AttributeIncludesPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeIncludesName, "a",
+ g => g.AttributeIncludesValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueIncludes()
+ {
+ Test("[*|a~=v]", g => g.AttributeIncludesPrefix,
NamespacePrefix.Any,
+ g => g.AttributeIncludesName, "a",
+ g => g.AttributeIncludesValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribueIncludes()
+ {
+ Test("[ns|a~=v]", g => g.AttributeIncludesPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeIncludesName, "a",
+ g => g.AttributeIncludesValue, "v");
+ }
+
+ [Test]
+ public void NoNamespaceAttribueDashMatch()
+ {
+ Test("[a|=v]", g => g.AttributeDashMatchPrefix,
NamespacePrefix.None,
+ g => g.AttributeDashMatchName, "a",
+ g => g.AttributeDashMatchValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueDashMatch()
+ {
+ Test("[|a|=v]", g => g.AttributeDashMatchPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeDashMatchName, "a",
+ g => g.AttributeDashMatchValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueDashMatch()
+ {
+ Test("[*|a|=v]", g => g.AttributeDashMatchPrefix,
NamespacePrefix.Any,
+ g => g.AttributeDashMatchName, "a",
+ g => g.AttributeDashMatchValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribueDashMatch()
+ {
+ Test("[ns|a|=v]", g => g.AttributeDashMatchPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeDashMatchName, "a",
+ g => g.AttributeDashMatchValue, "v");
+ }
+
+ [Test]
+ public void NoNamespaceAttribuePrefixMatch()
+ {
+ Test("[a^=v]", g => g.AttributePrefixMatchPrefix,
NamespacePrefix.None,
+ g => g.AttributePrefixMatchName, "a",
+ g => g.AttributePrefixMatchValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribuePrefixMatch()
+ {
+ Test("[|a^=v]", g => g.AttributePrefixMatchPrefix,
NamespacePrefix.Empty,
+ g => g.AttributePrefixMatchName, "a",
+ g => g.AttributePrefixMatchValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribuePrefixMatch()
+ {
+ Test("[*|a^=v]", g => g.AttributePrefixMatchPrefix,
NamespacePrefix.Any,
+ g => g.AttributePrefixMatchName, "a",
+ g => g.AttributePrefixMatchValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribuePrefixMatch()
+ {
+ Test("[ns|a^=v]", g => g.AttributePrefixMatchPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributePrefixMatchName, "a",
+ g => g.AttributePrefixMatchValue, "v");
+ }
+
+ [Test]
+ public void NoNamespaceAttribueSuffixMatch()
+ {
+ Test("[a$=v]", g => g.AttributeSuffixMatchPrefix,
NamespacePrefix.None,
+ g => g.AttributeSuffixMatchName, "a",
+ g => g.AttributeSuffixMatchValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueSuffixMatch()
+ {
+ Test("[|a$=v]", g => g.AttributeSuffixMatchPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeSuffixMatchName, "a",
+ g => g.AttributeSuffixMatchValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueSuffixMatch()
+ {
+ Test("[*|a$=v]", g => g.AttributeSuffixMatchPrefix,
NamespacePrefix.Any,
+ g => g.AttributeSuffixMatchName, "a",
+ g => g.AttributeSuffixMatchValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribueSuffixMatch()
+ {
+ Test("[ns|a$=v]", g => g.AttributeSuffixMatchPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeSuffixMatchName, "a",
+ g => g.AttributeSuffixMatchValue, "v");
+ }
+
+ [Test]
+ public void NoNamespaceAttribueSubstring()
+ {
+ Test("[a*=v]", g => g.AttributeSubstringPrefix,
NamespacePrefix.None,
+ g => g.AttributeSubstringName, "a",
+ g => g.AttributeSubstringValue, "v");
+ }
+
+ [Test]
+ public void EmptyNamespaceAttribueSubstring()
+ {
+ Test("[|a*=v]", g => g.AttributeSubstringPrefix,
NamespacePrefix.Empty,
+ g => g.AttributeSubstringName, "a",
+ g => g.AttributeSubstringValue, "v");
+ }
+
+ [Test]
+ public void AnyNamespaceAttribueSubstring()
+ {
+ Test("[*|a*=v]", g => g.AttributeSubstringPrefix,
NamespacePrefix.Any,
+ g => g.AttributeSubstringName, "a",
+ g => g.AttributeSubstringValue, "v");
+ }
+
+ [Test]
+ public void NamespacedAttribueSubstring()
+ {
+ Test("[ns|a*=v]", g => g.AttributeSubstringPrefix, new
NamespacePrefix("ns"),
+ g => g.AttributeSubstringName, "a",
+ g => g.AttributeSubstringValue, "v");
+ }
+
+ private static void Test<T1>(string input,
Func<TestSelectorGenerator, T1> actual1, T1 expected1)
+ {
+ Test(input,
+ new Func<TestSelectorGenerator, object>[] { g =>
actual1(g) },
+ new object[] { expected1 });
+ }
+
+ private static void Test<T1, T2>(string input,
+ Func<TestSelectorGenerator, T1> actual1, T1 expected1,
+ Func<TestSelectorGenerator, T2> actual2, T2 expected2)
+ {
+ Test(input,
+ new Func<TestSelectorGenerator, object>[] {g =>
actual1(g), g => actual2(g)},
+ new object[] {expected1, expected2});
+ }
+
+ private static void Test<T1, T2, T3>(string input,
+ Func<TestSelectorGenerator, T1> actual1, T1 expected1,
+ Func<TestSelectorGenerator, T2> actual2, T2 expected2,
+ Func<TestSelectorGenerator, T3> actual3, T2 expected3)
+ {
+ Test(input,
+ new Func<TestSelectorGenerator, object>[] { g =>
actual1(g), g => actual2(g), g => actual3(g) },
+ new object[] { expected1, expected2, expected3 });
+ }
+
+ private static void Test(string input,
+ IEnumerable<Func<TestSelectorGenerator, object>> actuals,
+ IEnumerable<object> expectations)
+ {
+ var generator = new TestSelectorGenerator();
+ Parser.Parse(Tokener.Tokenize(input), generator);
+ using (var actual = actuals.GetEnumerator())
+ using (var expected = expectations.GetEnumerator())
+ {
+ while(actual.MoveNext())
+ {
+ Assert.That(expected.MoveNext(), Is.True, "Missing
expectation");
+ Assert.That(actual.Current(generator),
Is.EqualTo(expected.Current));
+ }
+ Assert.That(expected.MoveNext(), Is.False, "Too many
expectations");
+ }
+ }
+
+ public class TestSelectorGenerator : ISelectorGenerator
+ {
+ public NamespacePrefix TypePrefix;
+ public string TypeName;
+
+ public NamespacePrefix UniversalPrefix;
+
+ public NamespacePrefix AttributeExistsPrefix;
+ public string AttributeExistsName;
+ public NamespacePrefix AttributeExactPrefix;
+ public string AttributeExactName;
+ public string AttributeExactValue;
+ public NamespacePrefix AttributeIncludesPrefix;
+ public string AttributeIncludesName;
+ public string AttributeIncludesValue;
+ public NamespacePrefix AttributeDashMatchPrefix;
+ public string AttributeDashMatchName;
+ public string AttributeDashMatchValue;
+ public NamespacePrefix AttributePrefixMatchPrefix;
+ public string AttributePrefixMatchName;
+ public string AttributePrefixMatchValue;
+ public NamespacePrefix AttributeSuffixMatchPrefix;
+ public string AttributeSuffixMatchName;
+ public string AttributeSuffixMatchValue;
+ public NamespacePrefix AttributeSubstringPrefix;
+ public string AttributeSubstringName;
+ public string AttributeSubstringValue;
+
+ public void Type(NamespacePrefix prefix, string name)
+ {
+ TypePrefix = prefix;
+ TypeName = name;
+ }
+
+ public void Universal(NamespacePrefix prefix)
+ {
+ UniversalPrefix = prefix;
+ }
+
+ public void AttributeExists(NamespacePrefix prefix, string
name)
+ {
+ AttributeExistsPrefix = prefix;
+ AttributeExistsName = name;
+ }
+
+ public void AttributeExact(NamespacePrefix prefix, string
name, string value)
+ {
+ AttributeExactPrefix = prefix;
+ AttributeExactName = name;
+ AttributeExactValue = value;
+ }
+
+ public void AttributeIncludes(NamespacePrefix prefix, string
name, string value)
+ {
+ AttributeIncludesPrefix = prefix;
+ AttributeIncludesName = name;
+ AttributeIncludesValue = value;
+ }
+
+ public void AttributeDashMatch(NamespacePrefix prefix, string
name, string value)
+ {
+ AttributeDashMatchPrefix = prefix;
+ AttributeDashMatchName = name;
+ AttributeDashMatchValue = value;
+ }
+
+ public void AttributePrefixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ AttributePrefixMatchPrefix = prefix;
+ AttributePrefixMatchName = name;
+ AttributePrefixMatchValue = value;
+ }
+
+ public void AttributeSuffixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ AttributeSuffixMatchPrefix = prefix;
+ AttributeSuffixMatchName = name;
+ AttributeSuffixMatchValue = value;
+ }
+
+ public void AttributeSubstring(NamespacePrefix prefix, string
name, string value)
+ {
+ AttributeSubstringPrefix = prefix;
+ AttributeSubstringName = name;
+ AttributeSubstringValue = value;
+ }
+
+ #region Unimplemented memebers
+
+ public void OnInit()
+ {
+ }
+
+ public void OnClose()
+ {
+ }
+
+ public void OnSelector()
+ {
+ }
+
+ public void Id(string id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Class(string clazz)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void FirstChild()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LastChild()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void NthChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnlyChild()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Empty()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Child()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Descendant()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Adjacent()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void GeneralSibling()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void NthLastChild(int a, int b)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/Properties/AssemblyInfo.cs Wed Oct 15 05:52:25 2014
UTC
@@ -0,0 +1,55 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the
following
+// set of attributes. Change these attribute values to modify the
information
+// associated with an assembly.
+[assembly: AssemblyTitle("Fizzle.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Fizzle.Tests")]
+[assembly: AssemblyCopyright("Copyright (c) 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM componenets. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is
exposed to COM
+[assembly: Guid("9f88a10e-c38f-4e08-bb13-3e99114958fc")]
+
+// Version information for an assembly consists of the following four
values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and
Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/PsuedoSelectors.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,59 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class PsuedoSelectors : SelectorBaseTest
+ {
+ [Test]
+ public void First_Child()
+ {
+ Assert.AreEqual(8, SelectList("*:first-child").Count);
+ Assert.AreEqual(1, SelectList("p:first-child").Count);
+ }
+
+ [Test]
+ public void Last_Child()
+ {
+ Assert.AreEqual(7, SelectList("*:last-child").Count);
+ Assert.AreEqual(2, SelectList("p:last-child").Count);
+ }
+
+ [Test]
+ public void Only_Child()
+ {
+ Assert.AreEqual(3, SelectList("*:only-child").Count);
+ Assert.AreEqual(1, SelectList("p:only-child").Count);
+ }
+
+ [Test]
+ public void Empty()
+ {
+ var results = SelectList("*:empty");
+ Assert.AreEqual(2, results.Count);
+ Assert.AreEqual("head", results[0].Name);
+ Assert.AreEqual("input", results[1].Name);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/ReaderTests.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,222 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using NUnit.Framework;
+
+ #endregion
+
+ [TestFixture]
+ public class ReaderTests
+ {
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullEnumeratorInitialization()
+ {
+ new Reader<int>((IEnumerator<int>)null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullEnumerableInitialization()
+ {
+ new Reader<int>((IEnumerable<int>)null);
+ }
+
+ [Test]
+ public void HasMoreWhenEmpty()
+ {
+ Assert.IsFalse(new Reader<int>(new int[0]).HasMore);
+ }
+
+ [Test]
+ public void HasMoreWhenNotEmpty()
+ {
+ Assert.IsTrue(new Reader<int>(new int[1]).HasMore);
+ }
+
+ [Test, ExpectedException(typeof(InvalidOperationException))]
+ public void ReadEmpty()
+ {
+ new Reader<int>(new int[0]).Read();
+ }
+
+ [Test]
+ public void Unreading()
+ {
+ var reader = new Reader<int>(new[] { 78, 910 });
+ reader.Unread(56);
+ reader.Unread(34);
+ reader.Unread(12);
+ Assert.AreEqual(12, reader.Read());
+ Assert.AreEqual(34, reader.Read());
+ Assert.AreEqual(56, reader.Read());
+ Assert.AreEqual(78, reader.Read());
+ Assert.AreEqual(910, reader.Read());
+ }
+
+ [Test, ExpectedException(typeof(InvalidOperationException))]
+ public void PeekEmpty()
+ {
+ new Reader<int>(new int[0]).Peek();
+ }
+
+ [Test]
+ public void PeekNonEmpty()
+ {
+ var reader = new Reader<int>(new[] { 12, 34, 56 });
+ Assert.AreEqual(12, reader.Peek());
+ Assert.AreEqual(12, reader.Read());
+ Assert.AreEqual(34, reader.Peek());
+ Assert.AreEqual(34, reader.Read());
+ Assert.AreEqual(56, reader.Peek());
+ Assert.AreEqual(56, reader.Read());
+ }
+
+ [Test]
+ public void Enumeration()
+ {
+ var e = new Reader<int>(new[] { 12, 34, 56 }).GetEnumerator();
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(12, e.Current);
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(34, e.Current);
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(56, e.Current);
+ Assert.IsFalse(e.MoveNext());
+ }
+
+ [Test]
+ public void EnumerationNonGeneric()
+ {
+ var e = ((IEnumerable) new Reader<int>(new[] { 12, 34, 56
})).GetEnumerator();
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(12, e.Current);
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(34, e.Current);
+ Assert.IsTrue(e.MoveNext());
+ Assert.AreEqual(56, e.Current);
+ Assert.IsFalse(e.MoveNext());
+ }
+
+ [Test]
+ public void CloseDisposes()
+ {
+ var e = new TestEnumerator<object>();
+ Assert.IsFalse(e.Disposed);
+ new Reader<object>(e).Close();
+ Assert.IsTrue(e.Disposed);
+ }
+
+ [Test]
+ public void DisposeDisposes()
+ {
+ var e = new TestEnumerator<object>();
+ Assert.IsFalse(e.Disposed);
+ ((IDisposable) new Reader<object>(e)).Dispose();
+ Assert.IsTrue(e.Disposed);
+ }
+
+ [Test]
+ public void DisposeDisposesOnce()
+ {
+ var e = new TestEnumerator<object>();
+ Assert.IsFalse(e.Disposed);
+ var disposable = ((IDisposable)new Reader<object>(e));
+ disposable.Dispose();
+ Assert.AreEqual(1, e.DisposeCallCount);
+ disposable.Dispose();
+ Assert.AreEqual(1, e.DisposeCallCount);
+ }
+
+ [Test, ExpectedException(typeof(ObjectDisposedException))]
+ public void HasMoreDisposed()
+ {
+ var unused = CreateDisposedReader<int>().HasMore;
+ }
+
+ [Test, ExpectedException(typeof(ObjectDisposedException))]
+ public void ReadDisposed()
+ {
+ CreateDisposedReader<int>().Read();
+ }
+
+ [Test, ExpectedException(typeof(ObjectDisposedException))]
+ public void UnreadDisposed()
+ {
+ CreateDisposedReader<int>().Unread(42);
+ }
+
+ [Test, ExpectedException(typeof(ObjectDisposedException))]
+ public void PeekDisposed()
+ {
+ CreateDisposedReader<int>().Peek();
+ }
+
+ [Test, ExpectedException(typeof(ObjectDisposedException))]
+ public void EnumerateDisposed()
+ {
+ CreateDisposedReader<int>().GetEnumerator();
+ }
+
+ private static Reader<T> CreateDisposedReader<T>()
+ {
+ var reader = new Reader<T>(new T[0]);
+ reader.Close();
+ return reader;
+ }
+
+ private sealed class TestEnumerator<T> : IEnumerator<T>
+ {
+ public int DisposeCallCount { get; set; }
+ public bool Disposed { get { return DisposeCallCount > 0; } }
+
+ public void Dispose()
+ {
+ DisposeCallCount++;
+ }
+
+ public bool MoveNext()
+ {
+ return false;
+ }
+
+ public void Reset()
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Current
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/SelectorBaseTest.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,68 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+ using Fizzler.Systems.HtmlAgilityPack;
+ using HtmlAgilityPack;
+
+ #endregion
+
+ public abstract class SelectorBaseTest
+ {
+ protected SelectorBaseTest()
+ {
+ string html;
+ var assembly = Assembly.GetExecutingAssembly();
+ const string resourceName = "Fizzler.Tests.SelectorTest.html";
+ using (var stream =
assembly.GetManifestResourceStream(resourceName))
+ {
+ if (stream == null)
+ throw new Exception(string.Format("Resource, named
{0}, not found.", resourceName));
+ using(var reader = new StreamReader(stream))
+ html = reader.ReadToEnd();
+ }
+ var document = new HtmlDocument();
+ document.LoadHtml2(html);
+ Document = document;
+ }
+
+ protected HtmlDocument Document { get; private set; }
+
+ protected IEnumerable<HtmlNode> Select(string selectorChain)
+ {
+ return Document.DocumentNode.QuerySelectorAll(selectorChain);
+ }
+
+ protected IList<HtmlNode> SelectList(string selectorChain)
+ {
+ return new
ReadOnlyCollection<HtmlNode>(Select(selectorChain).ToArray());
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/SelectorGeneratorTeeTests.cs Wed Oct 15 05:52:25
2014 UTC
@@ -0,0 +1,405 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection;
+ using NUnit.Framework;
+
+ #endregion
+
+ /// <summary>
+ /// Ensure that all actions on SelectorGeneratorTee are passed
+ /// to the internal Primary and Secondary SelectorGenerators.
+ /// </summary>
+ [TestFixture]
+ public class SelectorGeneratorTeeTests
+ {
+ private static SelectorGeneratorTee tee;
+ private static FakeSelectorGenerator primary;
+ private static FakeSelectorGenerator secondary;
+
+ [SetUp]
+ public void Setup()
+ {
+ primary = new FakeSelectorGenerator();
+ secondary = new FakeSelectorGenerator();
+ tee = new SelectorGeneratorTee(primary, secondary);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullPrimary()
+ {
+ new SelectorGeneratorTee(
+ null, new FakeSelectorGenerator()
+ );
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullSecondary()
+ {
+ new SelectorGeneratorTee(
+ new FakeSelectorGenerator(), null
+ );
+ }
+
+ [Test]
+ public void OnInitTest()
+ {
+ Run(tee.OnInit);
+ }
+
+ [Test]
+ public void OnCloseTest()
+ {
+ Run(tee.OnClose);
+ }
+
+ [Test]
+ public void OnSelectorTest()
+ {
+ Run(tee.OnSelector);
+ }
+
+ [Test]
+ public void TypeTest()
+ {
+ Run(tee.Type, NamespacePrefix.None, "go");
+ }
+
+ [Test]
+ public void UniversalTest()
+ {
+ Run(tee.Universal, NamespacePrefix.None);
+ }
+
+ [Test]
+ public void IdTest()
+ {
+ Run(tee.Id, "hello");
+ }
+
+ [Test]
+ public void ClassTest()
+ {
+ Run(tee.Class, "hello");
+ }
+
+ [Test]
+ public void AttrExistsTest()
+ {
+ Run(tee.AttributeExists, NamespacePrefix.None, "hello");
+ }
+
+ [Test]
+ public void AttExactTest()
+ {
+ Run(tee.AttributeExact,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrIncludesTest()
+ {
+ Run(tee.AttributeIncludes,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrDashMatchTest()
+ {
+ Run(tee.AttributeDashMatch,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrPrefixMatchTest()
+ {
+
Run(tee.AttributePrefixMatch,NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrSuffixMatchTest()
+ {
+ Run(tee.AttributeSuffixMatch,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void AttrSubstringTest()
+ {
+ Run(tee.AttributeSubstring,
NamespacePrefix.None, "hello", "there");
+ }
+
+ [Test]
+ public void FirstChildTest()
+ {
+ Run(tee.FirstChild);
+ }
+
+ [Test]
+ public void LastChildTest()
+ {
+ Run(tee.LastChild);
+ }
+
+ [Test]
+ public void NthChildTest()
+ {
+ Run(tee.NthChild, 1, 2);
+ }
+
+ [Test]
+ public void OnlyChildTest()
+ {
+ Run(tee.OnlyChild);
+ }
+
+ [Test]
+ public void EmptyTest()
+ {
+ Run(tee.Empty);
+ }
+
+ [Test]
+ public void ChildTest()
+ {
+ Run(tee.Child);
+ }
+
+ [Test]
+ public void DescendantTest()
+ {
+ Run(tee.Descendant);
+ }
+
+ [Test]
+ public void AdjacentTest()
+ {
+ Run(tee.Adjacent);
+ }
+
+ [Test]
+ public void GeneralSiblingTest()
+ {
+ Run(tee.GeneralSibling);
+ }
+
+ private static void Run(Action action)
+ {
+ RunImpl(action.Method);
+ }
+
+ private static void Run<T>(Action<T> action, T arg)
+ {
+ RunImpl(action.Method, arg);
+ }
+
+ private static void Run<T1, T2>(Action<T1, T2> action, T1 arg1, T2
arg2)
+ {
+ RunImpl(action.Method, arg1, arg2);
+ }
+
+ private static void Run<T1, T2, T3>(Action<T1, T2, T3> action, T1
arg1, T2 arg2, T3 arg3)
+ {
+ RunImpl(action.Method, arg1, arg2, arg3);
+ }
+
+ /// <summary>
+ /// Take the passed action, run it, and then check that the last
method
+ /// and last args are the same for pri and sec.
+ /// </summary>
+ private static void RunImpl(MethodBase action, params object[]
args)
+ {
+ var recordings = new
Queue<CallRecording<ISelectorGenerator>>(2);
+ primary.Recorder = recordings.Enqueue;
+ secondary.Recorder = recordings.Enqueue;
+
+ action.Invoke(tee, args);
+
+ // Assert the fact that the primary and secondary methods were
+ // both called with the same arguments and in the right order!
+
+ var recording = recordings.Dequeue();
+ Assert.AreSame(primary, recording.Target);
+ Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
+ Assert.AreEqual(args, recording.Arguments);
+
+ recording = recordings.Dequeue();
+ Assert.AreSame(secondary, recording.Target);
+ Assert.AreEqual(action.Name,
MapMethod<ISelectorGenerator>(recording.Method).Name);
+ Assert.AreEqual(args, recording.Arguments);
+ }
+
+ private static MethodInfo MapMethod<T>(MethodInfo method) where
T : class
+ {
+ var mapping = method.ReflectedType.GetInterfaceMap(typeof(T));
+ return mapping.InterfaceMethods
+ .Select((m, i) => new { Source = m, Target =
mapping.TargetMethods[i] })
+ .Single(m => m.Target == method).Source;
+ }
+
+ private sealed class CallRecording<T>
+ {
+ public T Target { get; private set; }
+ public MethodInfo Method { get; private set; }
+ public object[] Arguments { get; private set; }
+
+ public CallRecording(T target, MethodInfo method, object[]
arguments)
+ {
+ Target = target;
+ Method = method;
+ Arguments = arguments;
+ }
+ }
+
+ private sealed class FakeSelectorGenerator : ISelectorGenerator
+ {
+ public Action<CallRecording<ISelectorGenerator>> Recorder;
+
+ public void OnInit()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void OnClose()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void OnSelector()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Type(NamespacePrefix prefix, string type)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, type);
+ }
+
+ public void Universal(NamespacePrefix prefix)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix);
+ }
+
+ public void Id(string id)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), id);
+ }
+
+ public void Class(string clazz)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), clazz);
+ }
+
+ public void AttributeExists(NamespacePrefix prefix, string
name)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name);
+ }
+
+ public void AttributeExact(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeIncludes(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeDashMatch(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributePrefixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeSuffixMatch(NamespacePrefix prefix,
string name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void AttributeSubstring(NamespacePrefix prefix, string
name, string value)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), prefix, name,
value);
+ }
+
+ public void FirstChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void LastChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void NthChild(int a, int b)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), a, b);
+ }
+
+ public void OnlyChild()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Empty()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Child()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Descendant()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void Adjacent()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void GeneralSibling()
+ {
+ OnInvoked(MethodBase.GetCurrentMethod());
+ }
+
+ public void NthLastChild(int a, int b)
+ {
+ OnInvoked(MethodBase.GetCurrentMethod(), a, b);
+ }
+
+ private void OnInvoked(MethodBase method, params object[] args)
+ {
+ Recorder(new CallRecording<ISelectorGenerator>(this,
(MethodInfo) method, args));
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/SelectorTest.html Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,15 @@
+<html>
+<head></head>
+<body id="theBody">
+ <div id="myDiv">
+ <div id="someOtherDiv">subdiv!</div>
+ <p><a href="
http://www.google.com">hi</a><span
class="hyphen-separated">test</span><span>oh</span></p>
+ </div>
+ <p class="hiclass">hi!!</p>
+ <div class="checkit">wooo<p class="omg ohyeah">eeeee</p></div>
+ <div class="checkit">woootooo<a
href="
http://colinramsay.co.uk/">we</a></div>
+ <form>
+ <input />
+ </form>
+</body>
+</html>
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/TokenTests.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,301 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using NUnit.Framework;
+
+ #endregion
+
+ [TestFixture]
+ public class TokenTests
+ {
+ [Test]
+ public void DefaultState()
+ {
+ AssertToken(TokenKind.Eoi, new Token());
+ }
+
+ [Test]
+ public void Star()
+ {
+ AssertToken(TokenKind.Char, "*", Token.Star());
+ }
+
+ [Test]
+ public void Dot()
+ {
+ AssertToken(TokenKind.Char, ".", Token.Dot());
+ }
+
+ [Test]
+ public void Colon()
+ {
+ AssertToken(TokenKind.Char, ":", Token.Colon());
+ }
+
+ [Test]
+ public void Comma()
+ {
+ AssertToken(TokenKind.Char, ",", Token.Comma());
+
+ }
+
+ [Test]
+ public void Equals()
+ {
+ AssertToken(TokenKind.Char, "=", Token.Equals());
+
+ }
+
+ [Test]
+ public void LeftBracket()
+ {
+ AssertToken(TokenKind.Char, "[", Token.LeftBracket());
+
+ }
+
+ [Test]
+ public void RightBracket()
+ {
+ AssertToken(TokenKind.Char, "]", Token.RightBracket());
+ }
+
+ [Test]
+ public void Plus()
+ {
+ AssertToken(TokenKind.Plus, Token.Plus());
+ }
+
+ [Test]
+ public void Greater()
+ {
+ AssertToken(TokenKind.Greater, Token.Greater());
+ }
+
+ [Test]
+ public void RightParenthesis()
+ {
+ AssertToken(TokenKind.Char, ")", Token.RightParenthesis());
+ }
+
+ [Test]
+ public void Eoi()
+ {
+ AssertToken(TokenKind.Eoi, Token.Eoi());
+ }
+
+ [Test]
+ public void Includes()
+ {
+ AssertToken(TokenKind.Includes, Token.Includes());
+ }
+
+ [Test]
+ public void DashMatch()
+ {
+ AssertToken(TokenKind.DashMatch, Token.DashMatch());
+ }
+
+ [Test]
+ public void Ident()
+ {
+ AssertToken(TokenKind.Ident, "foo", Token.Ident("foo"));
+ }
+
+ [Test,ExpectedException(typeof(ArgumentNullException))]
+ public void IdentNullText()
+ {
+ Token.Ident(null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentException))]
+ public void IdentEmptyText()
+ {
+ Token.Ident(string.Empty);
+ }
+
+ [Test]
+ public void Hash()
+ {
+ AssertToken(TokenKind.Hash, "foo", Token.Hash("foo"));
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void HashNullText()
+ {
+ Token.Hash(null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentException))]
+ public void HashEmptyText()
+ {
+ Token.Hash(string.Empty);
+ }
+
+ [Test]
+ public void String()
+ {
+ AssertToken(TokenKind.String, "foo", Token.String("foo"));
+ }
+
+ [Test]
+ public void StringNullText()
+ {
+ Token.String(null);
+ }
+
+ [Test]
+ public void StringEmptyText()
+ {
+ AssertToken(TokenKind.String, string.Empty,
Token.String(string.Empty));
+ }
+
+ public void Function()
+ {
+ AssertToken(TokenKind.Function, "foo", Token.Function("foo"));
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void FunctionNullText()
+ {
+ Token.Function(null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentException))]
+ public void FunctionEmptyText()
+ {
+ Token.Function(string.Empty);
+ }
+
+ public void WhiteSpace()
+ {
+ AssertToken(TokenKind.WhiteSpace, " \n ",
Token.WhiteSpace("foo"));
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void WhiteSpaceNullText()
+ {
+ Token.WhiteSpace(null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentException))]
+ public void WhiteSpaceEmptyText()
+ {
+ Token.WhiteSpace(string.Empty);
+ }
+
+ public void Integer()
+ {
+ AssertToken(TokenKind.Integer, "123", Token.Integer("123"));
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void IntegerNullText()
+ {
+ Token.Integer(null);
+ }
+
+ [Test, ExpectedException(typeof(ArgumentException))]
+ public void IntegerEmptyText()
+ {
+ Token.Integer(string.Empty);
+ }
+
+ private static void AssertToken(TokenKind kindExpected, Token
token)
+ {
+ AssertToken(kindExpected, null, token);
+ }
+
+ private static void AssertToken(TokenKind expectedKind, string
expectedText, Token token)
+ {
+ Assert.AreEqual(expectedKind, token.Kind);
+ if (expectedText == null)
+ Assert.IsNull(token.Text);
+ else
+ Assert.AreEqual(expectedText, token.Text);
+ }
+
+ [Test]
+ public void PrefixMatch()
+ {
+ AssertToken(TokenKind.PrefixMatch, Token.PrefixMatch());
+ }
+
+ [Test]
+ public void SuffixMatch()
+ {
+ AssertToken(TokenKind.SuffixMatch, Token.SuffixMatch());
+ }
+
+ [Test]
+ public void SubstringMatch()
+ {
+ AssertToken(TokenKind.SubstringMatch, Token.SubstringMatch());
+ }
+
+ [Test]
+ public void GeneralSibling()
+ {
+ AssertToken(TokenKind.Tilde, Token.Tilde());
+ }
+
+ [Test]
+ public void Pipe()
+ {
+ var pipe = Token.Pipe();
+ Assert.That(pipe.Kind, Is.EqualTo(TokenKind.Char));
+ Assert.That(pipe.Text, Is.EqualTo("|"));
+ }
+
+ [Test]
+ public void StringRepresentations()
+ {
+ Assert.AreEqual("Eoi", Token.Eoi().ToString());
+ Assert.AreEqual("Ident: foo", Token.Ident("foo").ToString());
+ Assert.AreEqual("Hash: foo", Token.Hash("foo").ToString());
+ Assert.AreEqual("Includes", Token.Includes().ToString());
+ Assert.AreEqual("DashMatch", Token.DashMatch().ToString());
+ Assert.AreEqual("PrefixMatch", Token.PrefixMatch().ToString());
+ Assert.AreEqual("SuffixMatch", Token.SuffixMatch().ToString());
+ Assert.AreEqual("SubstringMatch",
Token.SubstringMatch().ToString());
+ Assert.AreEqual("String: foo", Token.String("foo").ToString());
+ Assert.AreEqual("Plus", Token.Plus().ToString());
+ Assert.AreEqual("Greater", Token.Greater().ToString());
+ Assert.AreEqual("WhiteSpace: ",
Token.WhiteSpace(" ").ToString());
+ Assert.AreEqual("Function: foo",
Token.Function("foo").ToString());
+ Assert.AreEqual("Integer: 42", Token.Integer("42").ToString());
+ Assert.AreEqual("Tilde", Token.Tilde().ToString());
+ Assert.AreEqual("Char: *", Token.Star().ToString());
+ Assert.AreEqual("Char: .", Token.Dot().ToString());
+ Assert.AreEqual("Char: :", Token.Colon().ToString());
+ Assert.AreEqual("Char: ,", Token.Comma().ToString());
+ Assert.AreEqual("Char: =", Token.Equals().ToString());
+ Assert.AreEqual("Char: [", Token.LeftBracket().ToString());
+ Assert.AreEqual("Char: ]", Token.RightBracket().ToString());
+ Assert.AreEqual("Char: )",
Token.RightParenthesis().ToString());
+ Assert.AreEqual("Char: |", Token.Pipe().ToString());
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/Fizzler.Tests/TokenerTests.cs Wed Oct 15 05:52:25 2014 UTC
@@ -0,0 +1,356 @@
+#region Copyright and License
+//
+// Fizzler - CSS Selector Engine for Microsoft .NET Framework
+// Copyright (c) 2009 Atif Aziz, Colin Ramsay. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or modify it
under
+// the terms of the GNU Lesser General Public License as published by the
Free
+// Software Foundation; either version 3 of the License, or (at your
option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful, but
WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation,
Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#endregion
+
+namespace Fizzler.Tests
+{
+ #region Imports
+
+ using System;
+ using System.IO;
+ using System.Linq;
+ using NUnit.Framework;
+
+ #endregion
+
+ [TestFixture]
+ public class TokenerTests
+ {
+ [Test]
+ public void NullInput()
+ {
+ Assert.AreEqual(Token.Eoi(), Tokener.Tokenize((string)
null).Single());
+ }
+
+ [Test]
+ public void EmptyInput()
+ {
+ Assert.AreEqual(Token.Eoi(),
Tokener.Tokenize(string.Empty).Single());
+ }
+
+ [Test]
+ public void WhiteSpace()
+ {
+ Assert.AreEqual(Token.WhiteSpace(" \r \n \f \t "),
Tokener.Tokenize(" \r \n \f \t etc").First());
+ }
+
+ [Test]
+ public void Colon()
+ {
+ Assert.AreEqual(Token.Colon(), Tokener.Tokenize(":").First());
+ }
+
+ [Test]
+ public void Comma()
+ {
+ Assert.AreEqual(Token.Comma(), Tokener.Tokenize(",").First());
+ }
+
+ [Test]
+ public void CommaWhiteSpacePrepended()
+ {
+ Assert.AreEqual(Token.Comma(),
Tokener.Tokenize(" ,").First());
+ }
+
+ [Test]
+ public void Plus()
+ {
+ Assert.AreEqual(Token.Plus(), Tokener.Tokenize("+").First());
+ }
+
+ [Test]
+ public void Equals()
+ {
+ Assert.AreEqual(Token.Equals(), Tokener.Tokenize("=").First());
+ }
+
+ [Test]
+ public void LeftBracket()
+ {
+ Assert.AreEqual(Token.LeftBracket(),
Tokener.Tokenize("[").First());
+ }
+
+ [Test]
+ public void RightBracket()
+ {
+ Assert.AreEqual(Token.RightBracket(),
Tokener.Tokenize("]").First());
+ }
+
+ [Test]
+ public void PlusWhiteSpacePrepended()
+ {
+ Assert.AreEqual(Token.Plus(), Tokener.Tokenize(" +").First());
+ }
+
+ [Test]
+ public void RightParenthesis()
+ {
+ Assert.AreEqual(Token.RightParenthesis(),
Tokener.Tokenize(")").First());
+ }
+
+ [Test]
+ public void Greater()
+ {
+ Assert.AreEqual(Token.Greater(),
Tokener.Tokenize(">").First());
+ }
+
+ [Test]
+ public void GreaterWhiteSpacePrepended()
+ {
+ Assert.AreEqual(Token.Greater(), Tokener.Tokenize("
>").First());
+ }
+
+ [Test]
+ public void IdentifierLowerCaseOnly()
+ {
+ Assert.AreEqual(Token.Ident("foo"),
Tokener.Tokenize("foo").First());
+ }
+
+ [Test]
+ public void IdentifierMixedCase()
+ {
+ Assert.AreEqual(Token.Ident("FoObAr"),
Tokener.Tokenize("FoObAr").First());
+ }
+
+ [Test]
+ public void IdentifierIncludingDigits()
+ {
+ Assert.AreEqual(Token.Ident("foobar42"),
Tokener.Tokenize("foobar42").First());
+ }
+
+ [Test]
+ public void IdentifierWithUnderscores()
+ {
+ Assert.AreEqual(Token.Ident("_foo_BAR_42_"),
Tokener.Tokenize("_foo_BAR_42_").First());
+ }
+
+ [Test]
+ public void IdentifierWithHypens()
+ {
+ Assert.AreEqual(Token.Ident("foo-BAR-42"),
Tokener.Tokenize("foo-BAR-42").First());
+ }
+
+ [Test]
+ public void IdentifierUsingVendorExtensionSyntax()
+ {
+ Assert.AreEqual(Token.Ident("-foo-BAR-42"),
Tokener.Tokenize("-foo-BAR-42").First());
+ }
+
+ [Test, ExpectedException(typeof(FormatException))]
+ public void
IdentifierUsingVendorExtensionSyntaxCannotBeginWithDigit()
+ {
+ Tokener.Tokenize("-42").ToArray();
+ }
+
+ [Test]
+ public void Hash()
+ {
+ Assert.AreEqual(Token.Hash("foo_BAR-baz-42"),
Tokener.Tokenize("#foo_BAR-baz-42").First());
+ }
+
+ [Test]
+ public void Includes()
+ {
+ Assert.AreEqual(TokenKind.Includes,
Tokener.Tokenize("~=").First().Kind);
+ }
+
+ [Test]
+ public void TildeTilde()
+ {
+ Assert.AreEqual(new[] { Token.Tilde(), Token.Tilde() },
Tokener.Tokenize("~~").Take(2).ToArray());
+ }
+
+ [Test]
+ public void DashMatch()
+ {
+ Assert.AreEqual(TokenKind.DashMatch, Tokener.Tokenize("|
=").First().Kind);
+ }
+
+ [Test]
+ public void Pipe()
+ {
+ Assert.AreEqual(new[] { Token.Char('|'), Token.Char('|') },
Tokener.Tokenize("||").Take(2).ToArray());
+ }
+
+ [Test]
+ public void StringSingleQuoted()
+ {
+ Assert.AreEqual(Token.String("foo bar"),
Tokener.Tokenize("'foo bar'").First());
+ }
+
+ [Test]
+ public void StringDoubleQuoted()
+ {
+ Assert.AreEqual(Token.String("foo bar"),
Tokener.Tokenize("\"foo bar\"").First());
+ }
+
+ [Test]
+ public void StringDoubleQuotedWithEscapedDoubleQuotes()
+ {
+ Assert.AreEqual(Token.String("foo \"bar\" baz"),
Tokener.Tokenize("\"foo \\\"bar\\\" baz\"").First());
+ }
+
+ [Test]
+ public void StringSingleQuotedWithEscapedSingleQuotes()
+ {
+ Assert.AreEqual(Token.String("foo 'bar' baz"),
Tokener.Tokenize(@"'foo \'bar\' baz'").First());
+ }
+
+ [Test]
+ public void StringDoubleQuotedWithEscapedBackslashes()
+ {
+ Assert.AreEqual(Token.String(@"foo \bar\ baz"),
Tokener.Tokenize("\"foo \\\\bar\\\\ baz\"").First());
+ }
+
+ [Test]
+ public void StringSingleQuotedWithEscapedBackslashes()
+ {
+ Assert.AreEqual(Token.String(@"foo \bar\ baz"),
Tokener.Tokenize(@"'foo \\bar\\ baz'").First());
+ }
+
+ [Test]
+ public void BracketedIdent()
+ {
+ var token = Tokener.Tokenize("[foo]").GetEnumerator();
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.LeftBracket(), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.Ident("foo"), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.RightBracket(), token.Current);
+ Assert.IsTrue(token.MoveNext()); Assert.AreEqual(Token.Eoi(),
token.Current);
+ Assert.IsFalse(token.MoveNext());
+ }
+
+ [Test, ExpectedException(typeof(FormatException))]
+ public void BadHash()
+ {
+ Tokener.Tokenize("#").ToArray();
+ }
+
+ [Test]
+ public void HashDelimitedCorrectly()
+ {
+ var token = Tokener.Tokenize("#foo.").GetEnumerator();
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.Hash("foo"), token.Current);
+ Assert.IsTrue(token.MoveNext()); Assert.AreEqual(Token.Dot(),
token.Current);
+ Assert.IsTrue(token.MoveNext()); Assert.AreEqual(Token.Eoi(),
token.Current);
+ Assert.IsFalse(token.MoveNext());
+ }
+
+ [Test]
+ public void Function()
+ {
+ Assert.AreEqual(Token.Function("funky"),
Tokener.Tokenize("funky(").First());
+ }
+
+ [Test]
+ public void FunctionWithEnclosedIdent()
+ {
+ var token = Tokener.Tokenize("foo(bar)").GetEnumerator();
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.Function("foo"), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.Ident("bar"), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.RightParenthesis(), token.Current);
+ Assert.IsTrue(token.MoveNext()); Assert.AreEqual(Token.Eoi(),
token.Current);
+ Assert.IsFalse(token.MoveNext());
+ }
+
+ [Test]
+ public void Integer()
+ {
+ Assert.AreEqual(Token.Integer("42"),
Tokener.Tokenize("42").First());
+ }
+
+ [Test]
+ public void IntegerEnclosed()
+ {
+ var token = Tokener.Tokenize("[42]").GetEnumerator();
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.LeftBracket(), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.Integer("42"), token.Current);
+ Assert.IsTrue(token.MoveNext());
Assert.AreEqual(Token.RightBracket(), token.Current);
+ Assert.IsTrue(token.MoveNext()); Assert.AreEqual(Token.Eoi(),
token.Current);
+ Assert.IsFalse(token.MoveNext());
+ }
+
+ [Test]
+ public void SubstringMatch()
+ {
+ Assert.AreEqual(TokenKind.SubstringMatch,
Tokener.Tokenize("*=").First().Kind);
+ }
+
+ [Test]
+ public void Star()
+ {
+ Assert.AreEqual(Token.Char('*'),
Tokener.Tokenize("*").First());
+ }
+
+ [Test]
+ public void StarStar()
+ {
+ Assert.AreEqual(new[] { Token.Char('*'), Token.Char('*') },
Tokener.Tokenize("**").Take(2).ToArray());
+ }
+
+ [Test]
+ public void Tilde()
+ {
+ Assert.AreEqual(TokenKind.Tilde,
Tokener.Tokenize("~").First().Kind);
+ }
+
+ [Test]
+ public void TildeWhitespacePrepended()
+ {
+ Assert.AreEqual(TokenKind.Tilde, Tokener.Tokenize("
~").First().Kind);
+ }
+
+ [Test,ExpectedException(typeof(FormatException))]
+ public void StringSingleQuoteUnterminated()
+ {
+ Tokener.Tokenize("'foo").ToArray();
+ }
+
+ [Test, ExpectedException(typeof(FormatException))]
+ public void StringDoubleQuoteUnterminated()
+ {
+ Tokener.Tokenize("\"foo").ToArray();
+ }
+
+ [Test, ExpectedException(typeof(FormatException))]
+ public void StringInvalidEscaping()
+ {
+ Tokener.Tokenize(@"'f\oo").ToArray();
+ }
+
+ [Test, ExpectedException(typeof(ArgumentNullException))]
+ public void NullReader()
+ {
+ Tokener.Tokenize((TextReader) null);
+ }
+
+ [Test]
+ public void StringReader()
+ {
+ Assert.AreEqual(new[] { Token.Integer("123"), Token.Comma(),
Token.Char('*'), Token.Eoi() },
+ Tokener.Tokenize(new StringReader("123,*")).ToArray());
+ }
+
+ [Test, ExpectedException(typeof(FormatException))]
+ public void InvalidChar()
+ {
+ Tokener.Tokenize("what?").ToArray();
+ }
+ }
+}
=======================================
***Additional files exist in this changeset.***
==============================================================================
Revision: 933b42313ad9
Branch: default
Author: azizatif
Date: Wed Oct 15 05:53:50 2014 UTC
Log: ReSharper settings migration
https://code.google.com/p/fizzler/source/detail?r=933b42313ad9
Modified:
/Fizzler.sln.DotSettings
=======================================
--- /Fizzler.sln.DotSettings Sat Jan 19 20:50:50 2013 UTC
+++ /Fizzler.sln.DotSettings Wed Oct 15 05:53:50 2014 UTC
@@ -22,5 +22,6 @@
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

</s:String>
+ <s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:String
x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data
/></s:String>
<s:String
x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters
/><ExcludeFilters
/></data></s:String></wpf:ResourceDictionary>
==============================================================================
Revision: 96da88c162ef
Branch: default
Author: azizatif
Date: Wed Oct 15 06:11:06 2014 UTC
Log: Version 1.0 with source packaging
https://code.google.com/p/fizzler/source/detail?r=96da88c162ef
Modified:
/Fizzler.Systems.HtmlAgilityPack.nuspec
/Fizzler.Tools.nuspec
/Fizzler.nuspec
/pack.cmd
=======================================
--- /Fizzler.Systems.HtmlAgilityPack.nuspec Wed Jan 23 21:44:55 2013 UTC
+++ /Fizzler.Systems.HtmlAgilityPack.nuspec Wed Oct 15 06:11:06 2014 UTC
@@ -2,7 +2,7 @@
<package xmlns="
http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Fizzler.Systems.HtmlAgilityPack</id>
- <version>1.0.0-beta2</version>
+ <version>1.0.0</version>
<title>Fizzler for HTML Agility Pack</title>
<authors>Atif Aziz, Colin Ramsay</authors>
<owners>Atif Aziz</owners>
@@ -16,21 +16,20 @@
<dependencies>
<group targetFramework=".NETFramework2.0">
<dependency id="HtmlAgilityPack" version="1.4.6" />
- <dependency id="Fizzler" version="1.0.0-beta2" />
+ <dependency id="Fizzler" version="1.0.0" />
<dependency id="LinqBridge" version="1.3.0" />
</group>
<group targetFramework=".NETFramework3.5">
<dependency id="HtmlAgilityPack" version="1.4.6" />
- <dependency id="Fizzler" version="1.0.0-beta2" />
+ <dependency id="Fizzler" version="1.0.0" />
</group>
</dependencies>
</metadata>
<files>
<file src="COPYING.txt" target="COPYING.txt" />
<file src="COPYING.LESSER.txt" target="COPYING.LESSER.txt" />
- <file
src="bin\NET-2.0\Release\Fizzler.Systems.HtmlAgilityPack.dll"
target="lib\net20\Fizzler.Systems.HtmlAgilityPack.dll" />
- <file
src="bin\NET-2.0\Release\Fizzler.Systems.HtmlAgilityPack.xml"
target="lib\net20\Fizzler.Systems.HtmlAgilityPack.xml" />
- <file src="bin\Release\Fizzler.Systems.HtmlAgilityPack.dll"
target="lib\net35\Fizzler.Systems.HtmlAgilityPack.dll" />
- <file src="bin\Release\Fizzler.Systems.HtmlAgilityPack.xml"
target="lib\net35\Fizzler.Systems.HtmlAgilityPack.xml" />
+ <file src="bin\NET-2.0\Release\Fizzler.Systems.HtmlAgilityPack.*"
target="lib\net20" />
+ <file src="bin\Release\Fizzler.Systems.HtmlAgilityPack.*"
target="lib\net35" />
+ <file src="src\**\*.cs" target="src"
exclude="src\Fizzler.Tests\**;src\Fizzler.Sandbox\**"/>
</files>
</package>
=======================================
--- /Fizzler.Tools.nuspec Wed Jan 23 21:42:23 2013 UTC
+++ /Fizzler.Tools.nuspec Wed Oct 15 06:11:06 2014 UTC
@@ -2,7 +2,7 @@
<package xmlns="
http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Fizzler.Tools</id>
- <version>1.0.0-beta2</version>
+ <version>1.0.0</version>
<title>Fizzler Tools</title>
<authors>Atif Aziz</authors>
<owners>Atif Aziz</owners>
@@ -17,17 +17,11 @@
<files>
<file src="COPYING.txt" target="COPYING.txt" />
<file src="COPYING.LESSER.txt" target="COPYING.LESSER.txt" />
- <file src="bin\Release\fizz.exe" target="tools\fizz.exe" />
- <file src="bin\Release\fizz.exe.config"
target="tools\fizz.exe.config" />
- <file src="bin\Release\fizz.pdb" target="tools\fizz.pdb" />
- <file src="bin\Release\Fizzler.dll" target="tools\Fizzler.dll" />
- <file src="bin\Release\Fizzler.pdb" target="tools\Fizzler.pdb" />
- <file src="bin\Release\Fizzler.Systems.HtmlAgilityPack.dll"
target="tools\Fizzler.Systems.HtmlAgilityPack.dll" />
- <file src="bin\Release\Fizzler.Systems.HtmlAgilityPack.pdb"
target="tools\Fizzler.Systems.HtmlAgilityPack.pdb" />
- <file src="bin\Release\HtmlAgilityPack.dll"
target="tools\HtmlAgilityPack.dll" />
- <file src="bin\Release\HtmlAgilityPack.pdb"
target="tools\HtmlAgilityPack.pdb" />
- <file src="bin\Release\Mannex.dll" target="tools\Mannex.dll" />
- <file src="bin\Release\VisualFizzler.exe"
target="tools\VisualFizzler.exe" />
- <file src="bin\Release\VisualFizzler.pdb"
target="tools\VisualFizzler.pdb" />
+ <file target="tools"
src="bin\Release\fizz.*"
exclude="bin\Release\*.xml" />
+ <file target="tools"
src="bin\Release\Fizzler.*"
exclude="bin\Release\*.xml;bin\Release\Fizzler.Sandbox.*" />
+ <file target="tools"
src="bin\Release\Fizzler.Systems.HtmlAgilityPack.*"
exclude="bin\Release\*.xml" />
+ <file target="tools"
src="bin\Release\HtmlAgilityPack.*"
exclude="bin\Release\*.xml" />
+ <file target="tools"
src="bin\Release\VisualFizzler.*"
exclude="bin\Release\*.xml" />
+ <file target="tools" src="bin\Release\Mannex.dll" />
</files>
</package>
=======================================
--- /Fizzler.nuspec Wed Jan 23 21:45:40 2013 UTC
+++ /Fizzler.nuspec Wed Oct 15 06:11:06 2014 UTC
@@ -2,7 +2,7 @@
<package xmlns="
http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>Fizzler</id>
- <version>1.0.0-beta2</version>
+ <version>1.0.0</version>
<title>Fizzler</title>
<authors>Atif Aziz, Colin Ramsay</authors>
<owners>Atif Aziz</owners>
@@ -23,9 +23,12 @@
<files>
<file src="COPYING.txt" target="COPYING.txt" />
<file src="COPYING.LESSER.txt" target="COPYING.LESSER.txt" />
- <file src="bin\NET-2.0\Release\Fizzler.dll"
target="lib\net20\Fizzler.dll" />
- <file src="bin\NET-2.0\Release\Fizzler.xml"
target="lib\net20\Fizzler.xml" />
- <file src="bin\Release\Fizzler.dll" target="lib\net35\Fizzler.dll"
/>
- <file src="bin\Release\Fizzler.xml" target="lib\net35\Fizzler.xml"
/>
+ <file src="bin\NET-2.0\Release\Fizzler.dll" target="lib\net20" />
+ <file src="bin\NET-2.0\Release\Fizzler.xml" target="lib\net20" />
+ <file src="bin\NET-2.0\Release\Fizzler.pdb" target="lib\net20" />
+ <file src="bin\Release\Fizzler.dll" target="lib\net35" />
+ <file src="bin\Release\Fizzler.xml" target="lib\net35" />
+ <file src="bin\Release\Fizzler.pdb" target="lib\net35" />
+ <file src="src\**\*.cs" target="src"
exclude="src\Fizzler.Tests\**;src\Fizzler.Sandbox\**"/>
</files>
</package>
=======================================
--- /pack.cmd Wed Jan 23 20:05:53 2013 UTC
+++ /pack.cmd Wed Oct 15 06:11:06 2014 UTC
@@ -10,7 +10,7 @@
if not %errorlevel%==0 exit /b %errorlevel%
set nupack=.nuget\NuGet pack -OutputDirectory dist
call build /v:m ^
- && %nupack% Fizzler.nuspec ^
- && %nupack% Fizzler.Systems.HtmlAgilityPack.nuspec ^
+ && %nupack% -Symbols Fizzler.nuspec ^
+ && %nupack% -Symbols Fizzler.Systems.HtmlAgilityPack.nuspec ^
&& %nupack% -NoPackageAnalysis Fizzler.Tools.nuspec
goto :EOF
==============================================================================
Revision: 0cc720824dd8
Branch: default
Author: azizatif
Date: Thu Oct 16 05:56:38 2014 UTC
Log: Added tag 1.0 for changeset 96da88c162ef
https://code.google.com/p/fizzler/source/detail?r=0cc720824dd8
Modified:
/.hgtags
=======================================
--- /.hgtags Wed Jan 23 21:53:37 2013 UTC
+++ /.hgtags Thu Oct 16 05:56:38 2014 UTC
@@ -1,3 +1,4 @@
a6642b810177c3db0310a2dbb64b4018ab94de50 0.9
77a0ac7f7479285d5ba3b3800906545394adc01a 1.0.0-beta1
ab420c22498394d1a1fc264b93fe09482597a58e 1.0.0-beta2
+96da88c162efa20f74f9b1995f42a911b1c86104 1.0