Many updates
This commit is contained in:
		@@ -1,16 +0,0 @@
 | 
			
		||||
@page "/counter"
 | 
			
		||||
 | 
			
		||||
<h1>Counter</h1>
 | 
			
		||||
 | 
			
		||||
<p>Current count: @currentCount</p>
 | 
			
		||||
 | 
			
		||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private int currentCount = 0;
 | 
			
		||||
 | 
			
		||||
    private void IncrementCount()
 | 
			
		||||
    {
 | 
			
		||||
        currentCount++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								Seenginx/Pages/Dmesg.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Seenginx/Pages/Dmesg.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
@page "/dmesg"
 | 
			
		||||
 | 
			
		||||
<h3>Dmesg</h3>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
@page "/fetchdata"
 | 
			
		||||
 | 
			
		||||
@using Seenginx.Data
 | 
			
		||||
@inject WeatherForecastService ForecastService
 | 
			
		||||
 | 
			
		||||
<h1>Weather forecast</h1>
 | 
			
		||||
 | 
			
		||||
<p>This component demonstrates fetching data from a service.</p>
 | 
			
		||||
 | 
			
		||||
@if (forecasts == null)
 | 
			
		||||
{
 | 
			
		||||
    <p><em>Loading...</em></p>
 | 
			
		||||
}
 | 
			
		||||
else
 | 
			
		||||
{
 | 
			
		||||
    <table class="table">
 | 
			
		||||
        <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th>Date</th>
 | 
			
		||||
                <th>Temp. (C)</th>
 | 
			
		||||
                <th>Temp. (F)</th>
 | 
			
		||||
                <th>Summary</th>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tbody>
 | 
			
		||||
            @foreach (var forecast in forecasts)
 | 
			
		||||
            {
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>@forecast.Date.ToShortDateString()</td>
 | 
			
		||||
                    <td>@forecast.TemperatureC</td>
 | 
			
		||||
                    <td>@forecast.TemperatureF</td>
 | 
			
		||||
                    <td>@forecast.Summary</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            }
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private WeatherForecast[] forecasts;
 | 
			
		||||
 | 
			
		||||
    protected override async Task OnInitializedAsync()
 | 
			
		||||
    {
 | 
			
		||||
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								Seenginx/Pages/Nginx.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Seenginx/Pages/Nginx.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
@page "/nginx"
 | 
			
		||||
 | 
			
		||||
<h3>Nginx</h3>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								Seenginx/Pages/Systemd.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Seenginx/Pages/Systemd.razor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
@page "/systemd"
 | 
			
		||||
 | 
			
		||||
<h3>SystemD</h3>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -13,15 +13,17 @@
 | 
			
		||||
	<link rel="icon" href="~/favicon.png" />
 | 
			
		||||
	<title>Seenginx</title>
 | 
			
		||||
	<base href="~/" />
 | 
			
		||||
	<link rel="stylesheet" href="~/css/side-menu.css" asp-append-version="true" />
 | 
			
		||||
	<environment include="Staging,Production">
 | 
			
		||||
		<link rel="stylesheet" href="~/css/open-iconic.min.css" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/pure.min.css" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/open-iconic.min.css" asp-append-version="true" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/pure.min.css" asp-append-version="true" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/main.min.css" asp-append-version="true" />
 | 
			
		||||
	</environment>
 | 
			
		||||
	<environment include="Development">
 | 
			
		||||
		<link rel="stylesheet" href="~/css/open-iconic.css" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/pure.css" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/open-iconic.css" asp-append-version="true" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/pure.css" asp-append-version="true" />
 | 
			
		||||
		<link rel="stylesheet" href="~/css/main.css" asp-append-version="true" />
 | 
			
		||||
	</environment>
 | 
			
		||||
	<link href="css/site.css" rel="stylesheet" />
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
	<app>
 | 
			
		||||
@@ -40,5 +42,7 @@
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<script src="_framework/blazor.server.js"></script>
 | 
			
		||||
	<script src="js/modal.js" asp-append-version="true"></script>
 | 
			
		||||
	<script src="js/ui.js" asp-append-version="true"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								Seenginx/SCSS/base.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Seenginx/SCSS/base.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
body {
 | 
			
		||||
	box-sizing: border-box
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*, ::before, ::after {
 | 
			
		||||
	box-sizing: inherit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#blazor-error-ui {
 | 
			
		||||
	background: lightyellow;
 | 
			
		||||
	bottom: 0;
 | 
			
		||||
	box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
 | 
			
		||||
	display: none;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	padding: 0.6rem 1.25rem 0.7rem 1.25rem;
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	z-index: 1000;
 | 
			
		||||
 | 
			
		||||
	& .dismiss {
 | 
			
		||||
		cursor: pointer;
 | 
			
		||||
		position: absolute;
 | 
			
		||||
		right: 0.75rem;
 | 
			
		||||
		top: 0.5rem;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								Seenginx/SCSS/main.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Seenginx/SCSS/main.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
@import "mixins.scss";
 | 
			
		||||
@import "base.scss";
 | 
			
		||||
@import "utility.scss";
 | 
			
		||||
@import "side-menu.scss";
 | 
			
		||||
							
								
								
									
										58
									
								
								Seenginx/SCSS/mixins.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Seenginx/SCSS/mixins.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
//MEDIA QUERY MANAGER
 | 
			
		||||
 | 
			
		||||
/*$breakpoint argument choices:
 | 
			
		||||
    - phone
 | 
			
		||||
    - tab-port
 | 
			
		||||
    - tab-land
 | 
			
		||||
    - desk
 | 
			
		||||
    - big-desktop
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
@mixin MediaQuery($breakpoint) {
 | 
			
		||||
	// max-width:600px;
 | 
			
		||||
	@if $breakpoint==phone {
 | 
			
		||||
		@media only screen and (max-width: 37.5em) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@if $breakpoint==tab-p {
 | 
			
		||||
		// min-width:601px;
 | 
			
		||||
		// max-width:900px;
 | 
			
		||||
		@media only screen and (min-width: 601px) and (max-width: 900px) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@if $breakpoint==tab-l {
 | 
			
		||||
		// min-width:901px;
 | 
			
		||||
		// max-width:1200px;
 | 
			
		||||
		@media only screen and (min-width: 901px) and (max-width: 1200px) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@if $breakpoint==laptop {
 | 
			
		||||
		// min-width:1201px;
 | 
			
		||||
		// max-width:1366px;
 | 
			
		||||
		@media only screen and (min-width: 1201px) and (max-width: 1366px) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@if $breakpoint==desk {
 | 
			
		||||
		// min-width:1201px;
 | 
			
		||||
		// max-width:1800px;
 | 
			
		||||
		@media only screen and (min-width: 1201px) and (max-width: 1800px) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@if $breakpoint==big-d {
 | 
			
		||||
		// min-width:1801px;
 | 
			
		||||
		// max-width:4000px;
 | 
			
		||||
		@media only screen and (min-width: 1801px) and (max-width: 4000px) {
 | 
			
		||||
			@content
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										182
									
								
								Seenginx/SCSS/side-menu.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								Seenginx/SCSS/side-menu.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
			
		||||
body {
 | 
			
		||||
	color: #777;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
	--leftPanel: 150px;
 | 
			
		||||
	--negativeLeftPanel: -150px;
 | 
			
		||||
	--mobileLeftPanel: 150px;
 | 
			
		||||
	--mobileNegativeLeftPanel: -150px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pure-img-responsive {
 | 
			
		||||
	max-width: 100%;
 | 
			
		||||
	height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Add transition to containers so they can push in and out.
 | 
			
		||||
*/
 | 
			
		||||
#layout,
 | 
			
		||||
#menu,
 | 
			
		||||
.menu-link {
 | 
			
		||||
	-webkit-transition: all 0.2s ease-out;
 | 
			
		||||
	-moz-transition: all 0.2s ease-out;
 | 
			
		||||
	-ms-transition: all 0.2s ease-out;
 | 
			
		||||
	-o-transition: all 0.2s ease-out;
 | 
			
		||||
	transition: all 0.2s ease-out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This is the parent `<div>` that contains the menu and the content area.
 | 
			
		||||
*/
 | 
			
		||||
#layout {
 | 
			
		||||
	position: relative;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	padding-left: 0;
 | 
			
		||||
 | 
			
		||||
	&.active {
 | 
			
		||||
 | 
			
		||||
		& .menu-link {
 | 
			
		||||
			left: var(--leftPanel);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		& #menu {
 | 
			
		||||
			left: var(--leftPanel);
 | 
			
		||||
			width: var(--leftPanel);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
The `#menu` `<div>` is the parent `<div>` that contains the `.pure-menu` that
 | 
			
		||||
appears on the left side of the page.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#menu {
 | 
			
		||||
	margin-left: var(--negativeLeftPanel); /* "#menu" width */
 | 
			
		||||
	width: var(--leftPanel);
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 0;
 | 
			
		||||
	left: 0;
 | 
			
		||||
	bottom: 0;
 | 
			
		||||
	z-index: 1000; /* so the menu or its navicon stays above all content */
 | 
			
		||||
	background: #191818;
 | 
			
		||||
	overflow-y: auto;
 | 
			
		||||
	-webkit-overflow-scrolling: touch;
 | 
			
		||||
	//All anchors inside the menu should be styled like this.
 | 
			
		||||
	& a {
 | 
			
		||||
		color: #999;
 | 
			
		||||
		border: none;
 | 
			
		||||
		padding: 0.6em 0 0.6em 0.6em;
 | 
			
		||||
	}
 | 
			
		||||
	//Remove all background/borders, since we are applying them to #menu.
 | 
			
		||||
	& .pure-menu,
 | 
			
		||||
	& .pure-menu ul {
 | 
			
		||||
		border: none;
 | 
			
		||||
		background: transparent;
 | 
			
		||||
	}
 | 
			
		||||
	//Add that light border to separate items into groups.
 | 
			
		||||
	& .pure-menu ul,
 | 
			
		||||
	& .pure-menu .menu-item-divided {
 | 
			
		||||
		border-top: 1px solid #333;
 | 
			
		||||
	}
 | 
			
		||||
	//Change color of the anchor links on hover/focus.
 | 
			
		||||
	& .pure-menu li a:hover,
 | 
			
		||||
	& .pure-menu li a:focus {
 | 
			
		||||
		background: #333;
 | 
			
		||||
	}
 | 
			
		||||
	//This styles the selected menu item `<li>`.
 | 
			
		||||
	& .pure-menu-selected,
 | 
			
		||||
	& .pure-menu-heading {
 | 
			
		||||
		background: #1f8dd6;
 | 
			
		||||
	}
 | 
			
		||||
	//This styles a link within a selected menu item `<li>`.
 | 
			
		||||
	& .pure-menu-selected a {
 | 
			
		||||
		color: #fff;
 | 
			
		||||
	}
 | 
			
		||||
	//This styles the menu heading.
 | 
			
		||||
	& .pure-menu-heading {
 | 
			
		||||
		font-size: 110%;
 | 
			
		||||
		color: #fff;
 | 
			
		||||
		margin: 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- Dynamic Button For Responsive Menu -------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
The button to open/close the Menu is custom-made and not part of Pure. Here's
 | 
			
		||||
how it works:
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
`.menu-link` represents the responsive menu toggle that shows/hides on
 | 
			
		||||
small screens.
 | 
			
		||||
*/
 | 
			
		||||
.menu-link {
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	display: block; /* show this only on small screens */
 | 
			
		||||
	top: 0;
 | 
			
		||||
	left: 0; /* "#menu width" */
 | 
			
		||||
	background: #000;
 | 
			
		||||
	background: rgba(0,0,0,0.7);
 | 
			
		||||
	font-size: 16px; /* change this value to increase/decrease button size */
 | 
			
		||||
	z-index: 10;
 | 
			
		||||
	width: min-content;
 | 
			
		||||
	height: auto;
 | 
			
		||||
	padding: 14px;
 | 
			
		||||
 | 
			
		||||
	&:hover,
 | 
			
		||||
	&:focus {
 | 
			
		||||
		background: #000;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -- Responsive Styles (Media Queries) ------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Hides the menu at `48em`, but modify this based on your app's needs.
 | 
			
		||||
*/
 | 
			
		||||
@media (min-width: 48em) {
 | 
			
		||||
 | 
			
		||||
	.header,
 | 
			
		||||
	.content {
 | 
			
		||||
		padding-left: 2em;
 | 
			
		||||
		padding-right: 2em;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#layout {
 | 
			
		||||
		padding-left: var(--leftPanel); /* left col width "#menu" */
 | 
			
		||||
		left: 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#menu {
 | 
			
		||||
		left: var(--leftPanel);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	.menu-link {
 | 
			
		||||
		position: fixed;
 | 
			
		||||
		left: var(--leftPanel);
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#layout.active .menu-link {
 | 
			
		||||
		left: var(--leftPanel);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 48em) {
 | 
			
		||||
	/* Only apply this when the window is small. Otherwise, the following
 | 
			
		||||
    case results in extra padding on the left:
 | 
			
		||||
        * Make the window small.
 | 
			
		||||
        * Tap the menu to trigger the active state.
 | 
			
		||||
        * Make the window large again.
 | 
			
		||||
    */
 | 
			
		||||
	#layout.active {
 | 
			
		||||
		position: relative;
 | 
			
		||||
		left: var(--leftPanel);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								Seenginx/SCSS/utility.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Seenginx/SCSS/utility.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
.isHidden {
 | 
			
		||||
	display: none;
 | 
			
		||||
 | 
			
		||||
	&Mobile {
 | 
			
		||||
		@include MediaQuery(phone) {
 | 
			
		||||
			display: none
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -5,8 +5,28 @@
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Folder Include="wwwroot\fonts\" />
 | 
			
		||||
    <Content Remove="compilerconfig.json" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Content Include="SCSS\side-menu.scss" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Folder Include="wwwroot\images\" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include="compilerconfig.json" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.3" />
 | 
			
		||||
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\Seenginx.Models\Seenginx.Models.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,14 @@
 | 
			
		||||
@inherits LayoutComponentBase
 | 
			
		||||
 | 
			
		||||
<div class="sidebar">
 | 
			
		||||
    <NavMenu />
 | 
			
		||||
<div id="layout" class="@MenuActiveClass">
 | 
			
		||||
 | 
			
		||||
	<NavMenu @bind-MenuActiveClass="MenuActiveClass" />
 | 
			
		||||
 | 
			
		||||
	<div id="main">
 | 
			
		||||
		@Body
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<div class="main">
 | 
			
		||||
    <div class="top-row px-4">
 | 
			
		||||
        <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="content px-4">
 | 
			
		||||
        @Body
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
@code{
 | 
			
		||||
	public string MenuActiveClass { get; set; } = null;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,37 +1,36 @@
 | 
			
		||||
<div class="top-row pl-4 navbar navbar-dark">
 | 
			
		||||
    <a class="navbar-brand" href="">Seenginx</a>
 | 
			
		||||
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
 | 
			
		||||
        <span class="navbar-toggler-icon"></span>
 | 
			
		||||
    </button>
 | 
			
		||||
</div>
 | 
			
		||||
@inherits NavMenuBase
 | 
			
		||||
 | 
			
		||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
 | 
			
		||||
    <ul class="nav flex-column">
 | 
			
		||||
        <li class="nav-item px-3">
 | 
			
		||||
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
 | 
			
		||||
                <span class="oi oi-home" aria-hidden="true"></span> Home
 | 
			
		||||
            </NavLink>
 | 
			
		||||
        </li>
 | 
			
		||||
        <li class="nav-item px-3">
 | 
			
		||||
            <NavLink class="nav-link" href="counter">
 | 
			
		||||
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
 | 
			
		||||
            </NavLink>
 | 
			
		||||
        </li>
 | 
			
		||||
        <li class="nav-item px-3">
 | 
			
		||||
            <NavLink class="nav-link" href="fetchdata">
 | 
			
		||||
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
 | 
			
		||||
            </NavLink>
 | 
			
		||||
        </li>
 | 
			
		||||
    </ul>
 | 
			
		||||
</div>
 | 
			
		||||
<a href="#menu" id="menuLink" class="menu-link @MenuActiveClass" @onclick="ToggleMenu">
 | 
			
		||||
	<span class="oi" data-glyph="menu"></span>
 | 
			
		||||
</a>
 | 
			
		||||
 | 
			
		||||
@code {
 | 
			
		||||
    private bool collapseNavMenu = true;
 | 
			
		||||
<div id="menu" class="@MenuActiveClass">
 | 
			
		||||
	<div class="pure-menu">
 | 
			
		||||
		<NavLink class="pure-menu-heading" href="/" Match="NavLinkMatch.All">
 | 
			
		||||
			<span class="oi" data-glyph="bolt"></span>
 | 
			
		||||
			<span class="isHiddenMobile">Seenginx</span>
 | 
			
		||||
		</NavLink>
 | 
			
		||||
 | 
			
		||||
    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
 | 
			
		||||
		<ul class="pure-menu-list">
 | 
			
		||||
			<li class="pure-menu-item @ActiveNav.GetValueOrDefault("nginx")">
 | 
			
		||||
				<NavLink href="/nginx" class="pure-menu-link" @onclick="@(e => SelectMenuItem("nginx"))">
 | 
			
		||||
					<span class="oi" data-glyph="code"></span>
 | 
			
		||||
					<span class="isHiddenMobile">NGINX</span>
 | 
			
		||||
				</NavLink>
 | 
			
		||||
			</li>
 | 
			
		||||
			<li class="pure-menu-item @ActiveNav.GetValueOrDefault("systemd")">
 | 
			
		||||
				<NavLink href="/systemd" class="pure-menu-link" @onclick="@(e => SelectMenuItem("systemd"))">
 | 
			
		||||
					<span class="oi" data-glyph="cog"></span>
 | 
			
		||||
					<span class="isHiddenMobile">SystemD</span>
 | 
			
		||||
				</NavLink>
 | 
			
		||||
			</li>
 | 
			
		||||
 | 
			
		||||
    private void ToggleNavMenu()
 | 
			
		||||
    {
 | 
			
		||||
        collapseNavMenu = !collapseNavMenu;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
			<li class="pure-menu-item @ActiveNav.GetValueOrDefault("dmesg")">
 | 
			
		||||
				<NavLink href="/dmesg" class="pure-menu-link" @onclick="@(e => SelectMenuItem("dmesg"))">
 | 
			
		||||
					<span class="oi" data-glyph="dashboard"></span>
 | 
			
		||||
					<span class="isHiddenMobile">Dmesg</span>
 | 
			
		||||
				</NavLink>
 | 
			
		||||
			</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										47
									
								
								Seenginx/Shared/NavMenu.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Seenginx/Shared/NavMenu.razor.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using Microsoft.AspNetCore.Components;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Seenginx.Shared
 | 
			
		||||
{
 | 
			
		||||
	public class NavMenuBase : ComponentBase
 | 
			
		||||
	{
 | 
			
		||||
		protected Dictionary<string, string> ActiveNav { get; set; }
 | 
			
		||||
		public bool CollapsePanel { get; set; } = false;
 | 
			
		||||
		[Parameter]
 | 
			
		||||
		public string MenuActiveClass { get; set; }
 | 
			
		||||
 | 
			
		||||
		[ParameterAttribute]
 | 
			
		||||
		public EventCallback<string> MenuActiveClassChanged { get; set; }
 | 
			
		||||
 | 
			
		||||
		protected async override Task OnInitializedAsync()
 | 
			
		||||
		{
 | 
			
		||||
			ActiveNav = new Dictionary<string, string>
 | 
			
		||||
			{
 | 
			
		||||
				{ "nginx", null },
 | 
			
		||||
				{ "systemd", null },
 | 
			
		||||
				{ "dmesg", null }
 | 
			
		||||
			};
 | 
			
		||||
			await base.OnInitializedAsync();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected void SelectMenuItem(string menuItem)
 | 
			
		||||
		{
 | 
			
		||||
			foreach (var key in ActiveNav.Keys.ToArray())
 | 
			
		||||
				ActiveNav[key] = null;
 | 
			
		||||
 | 
			
		||||
			ActiveNav[menuItem] = "pure-menu-selected";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected async Task ToggleMenu()
 | 
			
		||||
		{
 | 
			
		||||
			CollapsePanel = !CollapsePanel;
 | 
			
		||||
			MenuActiveClass = CollapsePanel ? "active" : null;
 | 
			
		||||
 | 
			
		||||
			await MenuActiveClassChanged.InvokeAsync(MenuActiveClass);
 | 
			
		||||
			StateHasChanged();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Hosting;
 | 
			
		||||
using Seenginx.Data;
 | 
			
		||||
using Seenginx.Services;
 | 
			
		||||
 | 
			
		||||
namespace Seenginx
 | 
			
		||||
@@ -26,11 +25,15 @@ namespace Seenginx
 | 
			
		||||
		// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
 | 
			
		||||
		public void ConfigureServices(IServiceCollection services)
 | 
			
		||||
		{
 | 
			
		||||
			services.AddRazorPages();
 | 
			
		||||
			services.AddRazorPages()
 | 
			
		||||
#if DEBUG
 | 
			
		||||
				.AddRazorRuntimeCompilation()
 | 
			
		||||
#endif
 | 
			
		||||
				;
 | 
			
		||||
			services.AddServerSideBlazor();
 | 
			
		||||
			services.AddTransient<IDmesgService,DmesgService>();
 | 
			
		||||
			services.AddTransient<INginxService,NginxService>();
 | 
			
		||||
			services.AddTransient<ISystemDService,SystemDService>();
 | 
			
		||||
			services.AddTransient<IDmesgService, DmesgService>();
 | 
			
		||||
			services.AddTransient<INginxService, NginxService>();
 | 
			
		||||
			services.AddTransient<ISystemDService, SystemDService>();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								Seenginx/compilerconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Seenginx/compilerconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "outputFile": "wwwroot/css/main.css",
 | 
			
		||||
    "inputFile": "SCSS/main.scss"
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										63
									
								
								Seenginx/compilerconfig.json.defaults
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Seenginx/compilerconfig.json.defaults
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilers": {
 | 
			
		||||
    "less": {
 | 
			
		||||
      "autoPrefix": "",
 | 
			
		||||
      "cssComb": "none",
 | 
			
		||||
      "ieCompat": true,
 | 
			
		||||
      "strictMath": false,
 | 
			
		||||
      "strictUnits": false,
 | 
			
		||||
      "relativeUrls": true,
 | 
			
		||||
      "rootPath": "",
 | 
			
		||||
      "sourceMapRoot": "",
 | 
			
		||||
      "sourceMapBasePath": "",
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    },
 | 
			
		||||
    "sass": {
 | 
			
		||||
      "autoPrefix": "",
 | 
			
		||||
      "includePath": "",
 | 
			
		||||
      "indentType": "space",
 | 
			
		||||
      "indentWidth": 2,
 | 
			
		||||
      "outputStyle": "nested",
 | 
			
		||||
      "Precision": 5,
 | 
			
		||||
      "relativeUrls": true,
 | 
			
		||||
      "sourceMapRoot": "",
 | 
			
		||||
      "lineFeed": "",
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    },
 | 
			
		||||
    "stylus": {
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    },
 | 
			
		||||
    "babel": {
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    },
 | 
			
		||||
    "coffeescript": {
 | 
			
		||||
      "bare": false,
 | 
			
		||||
      "runtimeMode": "node",
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    },
 | 
			
		||||
    "handlebars": {
 | 
			
		||||
      "root": "",
 | 
			
		||||
      "noBOM": false,
 | 
			
		||||
      "name": "",
 | 
			
		||||
      "namespace": "",
 | 
			
		||||
      "knownHelpersOnly": false,
 | 
			
		||||
      "forcePartial": false,
 | 
			
		||||
      "knownHelpers": [],
 | 
			
		||||
      "commonjs": "",
 | 
			
		||||
      "amd": false,
 | 
			
		||||
      "sourceMap": false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "minifiers": {
 | 
			
		||||
    "css": {
 | 
			
		||||
      "enabled": true,
 | 
			
		||||
      "termSemicolons": true,
 | 
			
		||||
      "gzip": false
 | 
			
		||||
    },
 | 
			
		||||
    "javascript": {
 | 
			
		||||
      "enabled": true,
 | 
			
		||||
      "termSemicolons": true,
 | 
			
		||||
      "gzip": false
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								Seenginx/wwwroot/css/main.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								Seenginx/wwwroot/css/main.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
/*$breakpoint argument choices:
 | 
			
		||||
    - phone
 | 
			
		||||
    - tab-port
 | 
			
		||||
    - tab-land
 | 
			
		||||
    - desk
 | 
			
		||||
    - big-desktop
 | 
			
		||||
    */
 | 
			
		||||
body {
 | 
			
		||||
  box-sizing: border-box; }
 | 
			
		||||
 | 
			
		||||
*, ::before, ::after {
 | 
			
		||||
  box-sizing: inherit; }
 | 
			
		||||
 | 
			
		||||
#blazor-error-ui {
 | 
			
		||||
  background: lightyellow;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
 | 
			
		||||
  display: none;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  padding: 0.6rem 1.25rem 0.7rem 1.25rem;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  z-index: 1000; }
 | 
			
		||||
  #blazor-error-ui .dismiss {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: 0.75rem;
 | 
			
		||||
    top: 0.5rem; }
 | 
			
		||||
 | 
			
		||||
.isHidden {
 | 
			
		||||
  display: none; }
 | 
			
		||||
  @media only screen and (max-width: 37.5em) {
 | 
			
		||||
    .isHiddenMobile {
 | 
			
		||||
      display: none; } }
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  color: #777; }
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
  --leftPanel: 150px;
 | 
			
		||||
  --negativeLeftPanel: -150px;
 | 
			
		||||
  --mobileLeftPanel: 150px;
 | 
			
		||||
  --mobileNegativeLeftPanel: -150px; }
 | 
			
		||||
 | 
			
		||||
.pure-img-responsive {
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  height: auto; }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Add transition to containers so they can push in and out.
 | 
			
		||||
*/
 | 
			
		||||
#layout,
 | 
			
		||||
#menu,
 | 
			
		||||
.menu-link {
 | 
			
		||||
  -webkit-transition: all 0.2s ease-out;
 | 
			
		||||
  -moz-transition: all 0.2s ease-out;
 | 
			
		||||
  -ms-transition: all 0.2s ease-out;
 | 
			
		||||
  -o-transition: all 0.2s ease-out;
 | 
			
		||||
  transition: all 0.2s ease-out; }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This is the parent `<div>` that contains the menu and the content area.
 | 
			
		||||
*/
 | 
			
		||||
#layout {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  padding-left: 0; }
 | 
			
		||||
  #layout.active .menu-link {
 | 
			
		||||
    left: var(--leftPanel); }
 | 
			
		||||
  #layout.active #menu {
 | 
			
		||||
    left: var(--leftPanel);
 | 
			
		||||
    width: var(--leftPanel); }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
The `#menu` `<div>` is the parent `<div>` that contains the `.pure-menu` that
 | 
			
		||||
appears on the left side of the page.
 | 
			
		||||
*/
 | 
			
		||||
#menu {
 | 
			
		||||
  margin-left: var(--negativeLeftPanel);
 | 
			
		||||
  /* "#menu" width */
 | 
			
		||||
  width: var(--leftPanel);
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  z-index: 1000;
 | 
			
		||||
  /* so the menu or its navicon stays above all content */
 | 
			
		||||
  background: #191818;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  -webkit-overflow-scrolling: touch; }
 | 
			
		||||
  #menu a {
 | 
			
		||||
    color: #999;
 | 
			
		||||
    border: none;
 | 
			
		||||
    padding: 0.6em 0 0.6em 0.6em; }
 | 
			
		||||
  #menu .pure-menu,
 | 
			
		||||
  #menu .pure-menu ul {
 | 
			
		||||
    border: none;
 | 
			
		||||
    background: transparent; }
 | 
			
		||||
  #menu .pure-menu ul,
 | 
			
		||||
  #menu .pure-menu .menu-item-divided {
 | 
			
		||||
    border-top: 1px solid #333; }
 | 
			
		||||
  #menu .pure-menu li a:hover,
 | 
			
		||||
  #menu .pure-menu li a:focus {
 | 
			
		||||
    background: #333; }
 | 
			
		||||
  #menu .pure-menu-selected,
 | 
			
		||||
  #menu .pure-menu-heading {
 | 
			
		||||
    background: #1f8dd6; }
 | 
			
		||||
  #menu .pure-menu-selected a {
 | 
			
		||||
    color: #fff; }
 | 
			
		||||
  #menu .pure-menu-heading {
 | 
			
		||||
    font-size: 110%;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    margin: 0; }
 | 
			
		||||
 | 
			
		||||
/* -- Dynamic Button For Responsive Menu -------------------------------------*/
 | 
			
		||||
/*
 | 
			
		||||
The button to open/close the Menu is custom-made and not part of Pure. Here's
 | 
			
		||||
how it works:
 | 
			
		||||
*/
 | 
			
		||||
/*
 | 
			
		||||
`.menu-link` represents the responsive menu toggle that shows/hides on
 | 
			
		||||
small screens.
 | 
			
		||||
*/
 | 
			
		||||
.menu-link {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  display: block;
 | 
			
		||||
  /* show this only on small screens */
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  /* "#menu width" */
 | 
			
		||||
  background: #000;
 | 
			
		||||
  background: rgba(0, 0, 0, 0.7);
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  /* change this value to increase/decrease button size */
 | 
			
		||||
  z-index: 10;
 | 
			
		||||
  width: min-content;
 | 
			
		||||
  height: auto;
 | 
			
		||||
  padding: 14px; }
 | 
			
		||||
  .menu-link:hover, .menu-link:focus {
 | 
			
		||||
    background: #000; }
 | 
			
		||||
 | 
			
		||||
/* -- Responsive Styles (Media Queries) ------------------------------------- */
 | 
			
		||||
/*
 | 
			
		||||
Hides the menu at `48em`, but modify this based on your app's needs.
 | 
			
		||||
*/
 | 
			
		||||
@media (min-width: 48em) {
 | 
			
		||||
  .header,
 | 
			
		||||
  .content {
 | 
			
		||||
    padding-left: 2em;
 | 
			
		||||
    padding-right: 2em; }
 | 
			
		||||
  #layout {
 | 
			
		||||
    padding-left: var(--leftPanel);
 | 
			
		||||
    /* left col width "#menu" */
 | 
			
		||||
    left: 0; }
 | 
			
		||||
  #menu {
 | 
			
		||||
    left: var(--leftPanel); }
 | 
			
		||||
  .menu-link {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: var(--leftPanel);
 | 
			
		||||
    display: none; }
 | 
			
		||||
  #layout.active .menu-link {
 | 
			
		||||
    left: var(--leftPanel); } }
 | 
			
		||||
 | 
			
		||||
@media (max-width: 48em) {
 | 
			
		||||
  /* Only apply this when the window is small. Otherwise, the following
 | 
			
		||||
    case results in extra padding on the left:
 | 
			
		||||
        * Make the window small.
 | 
			
		||||
        * Tap the menu to trigger the active state.
 | 
			
		||||
        * Make the window large again.
 | 
			
		||||
    */
 | 
			
		||||
  #layout.active {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    left: var(--leftPanel); } }
 | 
			
		||||
							
								
								
									
										1
									
								
								Seenginx/wwwroot/css/main.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Seenginx/wwwroot/css/main.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
body{box-sizing:border-box;}*,::before,::after{box-sizing:inherit;}#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}.isHidden{display:none;}@media only screen and (max-width:37.5em){.isHiddenMobile{display:none;}}body{color:#777;}:root{--leftPanel:150px;--negativeLeftPanel:-150px;--mobileLeftPanel:150px;--mobileNegativeLeftPanel:-150px;}.pure-img-responsive{max-width:100%;height:auto;}#layout,#menu,.menu-link{-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-ms-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;}#layout{position:relative;left:0;padding-left:0;}#layout.active .menu-link{left:var(--leftPanel);}#layout.active #menu{left:var(--leftPanel);width:var(--leftPanel);}#menu{margin-left:var(--negativeLeftPanel);width:var(--leftPanel);position:fixed;top:0;left:0;bottom:0;z-index:1000;background:#191818;overflow-y:auto;-webkit-overflow-scrolling:touch;}#menu a{color:#999;border:none;padding:.6em 0 .6em .6em;}#menu .pure-menu,#menu .pure-menu ul{border:none;background:transparent;}#menu .pure-menu ul,#menu .pure-menu .menu-item-divided{border-top:1px solid #333;}#menu .pure-menu li a:hover,#menu .pure-menu li a:focus{background:#333;}#menu .pure-menu-selected,#menu .pure-menu-heading{background:#1f8dd6;}#menu .pure-menu-selected a{color:#fff;}#menu .pure-menu-heading{font-size:110%;color:#fff;margin:0;}.menu-link{position:fixed;display:block;top:0;left:0;background:#000;background:rgba(0,0,0,.7);font-size:16px;z-index:10;width:min-content;height:auto;padding:14px;}.menu-link:hover,.menu-link:focus{background:#000;}@media(min-width:48em){.header,.content{padding-left:2em;padding-right:2em;}#layout{padding-left:var(--leftPanel);left:0;}#menu{left:var(--leftPanel);}.menu-link{position:fixed;left:var(--leftPanel);display:none;}#layout.active .menu-link{left:var(--leftPanel);}}@media(max-width:48em){#layout.active{position:relative;left:var(--leftPanel);}}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
body {
 | 
			
		||||
	box-sizing: border-box
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*, ::before, ::after {
 | 
			
		||||
	box-sizing: inherit
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										540
									
								
								Seenginx/wwwroot/js/modal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										540
									
								
								Seenginx/wwwroot/js/modal.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,540 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * CSS Modal
 | 
			
		||||
 * http://drublic.github.com/css-modal
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hans Christian Reinl - @drublic
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function (global, $) {
 | 
			
		||||
 | 
			
		||||
	'use strict';
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Storage for functions and attributes
 | 
			
		||||
	 */
 | 
			
		||||
	var modal = {
 | 
			
		||||
 | 
			
		||||
		activeElement: undefined, // Store for currently active element
 | 
			
		||||
		lastActive: undefined, // Store for last active elemet
 | 
			
		||||
		stackedElements: [], // Store for stacked elements
 | 
			
		||||
 | 
			
		||||
		// All elements that can get focus, can be tabbed in a modal
 | 
			
		||||
		tabbableElements: 'a[href], area[href], input:not([disabled]),' +
 | 
			
		||||
			'select:not([disabled]), textarea:not([disabled]),' +
 | 
			
		||||
			'button:not([disabled]), iframe, object, embed, *[tabindex],' +
 | 
			
		||||
			'*[contenteditable]',
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Polyfill addEventListener for IE8 (only very basic)
 | 
			
		||||
		 * @param event {string} event type
 | 
			
		||||
		 * @param element {Node} node to fire event on
 | 
			
		||||
		 * @param callback {function} gets fired if event is triggered
 | 
			
		||||
		 */
 | 
			
		||||
		on: function (event, elements, callback) {
 | 
			
		||||
			var i = 0;
 | 
			
		||||
 | 
			
		||||
			if (typeof event !== 'string') {
 | 
			
		||||
				throw new Error('Type error: `event` has to be a string');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (typeof callback !== 'function') {
 | 
			
		||||
				throw new Error('Type error: `callback` has to be a function');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!elements) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Make elements an array and attach event listeners
 | 
			
		||||
			if (!elements.length) {
 | 
			
		||||
				elements = [elements];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (; i < elements.length; i++) {
 | 
			
		||||
 | 
			
		||||
				// If jQuery is supported
 | 
			
		||||
				if ($) {
 | 
			
		||||
					$(elements[i]).on(event, callback);
 | 
			
		||||
 | 
			
		||||
				// Default way to support events
 | 
			
		||||
				} else if ('addEventListener' in elements[i]) {
 | 
			
		||||
					elements[i].addEventListener(event, callback, false);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Convenience function to trigger event
 | 
			
		||||
		 * @param event {string} event type
 | 
			
		||||
		 * @param modal {string} id of modal that the event is triggered on
 | 
			
		||||
		 */
 | 
			
		||||
		trigger: function (event, modal) {
 | 
			
		||||
			var eventTrigger;
 | 
			
		||||
			var eventParams = {
 | 
			
		||||
				detail: {
 | 
			
		||||
					'modal': modal
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			// Use jQuery to fire the event if it is included
 | 
			
		||||
			if ($) {
 | 
			
		||||
				$(document).trigger(event, eventParams);
 | 
			
		||||
 | 
			
		||||
			// Use createEvent if supported (that's mostly the case)
 | 
			
		||||
			} else if (document.createEvent) {
 | 
			
		||||
				eventTrigger = document.createEvent('CustomEvent');
 | 
			
		||||
 | 
			
		||||
				eventTrigger.initCustomEvent(event, false, false, {
 | 
			
		||||
					'modal': modal
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				document.dispatchEvent(eventTrigger);
 | 
			
		||||
 | 
			
		||||
			// Use CustomEvents if supported
 | 
			
		||||
			} else {
 | 
			
		||||
				eventTrigger = new CustomEvent(event, eventParams);
 | 
			
		||||
 | 
			
		||||
				document.dispatchEvent(eventTrigger);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Convenience function to add a class to an element
 | 
			
		||||
		 * @param element {Node} element to add class to
 | 
			
		||||
		 * @param className {string}
 | 
			
		||||
		 */
 | 
			
		||||
		addClass: function (element, className) {
 | 
			
		||||
			if (element && !element.className.match(className)) {
 | 
			
		||||
				element.className += ' ' + className;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Convenience function to remove a class from an element
 | 
			
		||||
		 * @param element {Node} element to remove class off
 | 
			
		||||
		 * @param className {string}
 | 
			
		||||
		 */
 | 
			
		||||
		removeClass: function (element, className) {
 | 
			
		||||
			element.className = element.className.replace(className, '').replace('  ', ' ');
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Convenience function to check if an element has a class
 | 
			
		||||
		 * @param  {Node}    element   Element to check classname on
 | 
			
		||||
		 * @param  {string}  className Class name to check for
 | 
			
		||||
		 * @return {Boolean}           true, if class is available on modal
 | 
			
		||||
		 */
 | 
			
		||||
		hasClass: function (element, className) {
 | 
			
		||||
			return !!element.className.match(className);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Focus modal
 | 
			
		||||
		 */
 | 
			
		||||
		setFocus: function () {
 | 
			
		||||
			if (modal.activeElement) {
 | 
			
		||||
 | 
			
		||||
				// Set element with last focus
 | 
			
		||||
				modal.lastActive = document.activeElement;
 | 
			
		||||
 | 
			
		||||
				// New focussing
 | 
			
		||||
				modal.activeElement.focus();
 | 
			
		||||
 | 
			
		||||
				// Add handler to keep the focus
 | 
			
		||||
				modal.keepFocus(modal.activeElement);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Unfocus
 | 
			
		||||
		 */
 | 
			
		||||
		removeFocus: function () {
 | 
			
		||||
			if (modal.lastActive) {
 | 
			
		||||
				modal.lastActive.focus();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Keep focus inside the modal
 | 
			
		||||
		 * @param element {node} element to keep focus in
 | 
			
		||||
		 */
 | 
			
		||||
		keepFocus: function (element) {
 | 
			
		||||
			var allTabbableElements = [];
 | 
			
		||||
 | 
			
		||||
			// Don't keep the focus if the browser is unable to support
 | 
			
		||||
			// CSS3 selectors
 | 
			
		||||
			try {
 | 
			
		||||
				allTabbableElements = element.querySelectorAll(modal.tabbableElements);
 | 
			
		||||
			} catch (ex) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var firstTabbableElement = modal.getFirstElementVisible(allTabbableElements);
 | 
			
		||||
			var lastTabbableElement = modal.getLastElementVisible(allTabbableElements);
 | 
			
		||||
 | 
			
		||||
			var focusHandler = function (event) {
 | 
			
		||||
				var keyCode = event.which || event.keyCode;
 | 
			
		||||
 | 
			
		||||
				// TAB pressed
 | 
			
		||||
				if (keyCode !== 9) {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Polyfill to prevent the default behavior of events
 | 
			
		||||
				event.preventDefault = event.preventDefault || function () {
 | 
			
		||||
					event.returnValue = false;
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				// Move focus to first element that can be tabbed if Shift isn't used
 | 
			
		||||
				if (event.target === lastTabbableElement && !event.shiftKey) {
 | 
			
		||||
					event.preventDefault();
 | 
			
		||||
					firstTabbableElement.focus();
 | 
			
		||||
 | 
			
		||||
				// Move focus to last element that can be tabbed if Shift is used
 | 
			
		||||
				} else if (event.target === firstTabbableElement && event.shiftKey) {
 | 
			
		||||
					event.preventDefault();
 | 
			
		||||
					lastTabbableElement.focus();
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			modal.on('keydown', element, focusHandler);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Return the first visible element of a nodeList
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param nodeList The nodelist to parse
 | 
			
		||||
		 * @return {Node|null} Returns a specific node or null if no element found
 | 
			
		||||
		 */
 | 
			
		||||
		getFirstElementVisible: function (nodeList) {
 | 
			
		||||
			var nodeListLength = nodeList.length;
 | 
			
		||||
 | 
			
		||||
			// If the first item is not visible
 | 
			
		||||
			if (!modal.isElementVisible(nodeList[0])) {
 | 
			
		||||
				for (var i = 1; i < nodeListLength - 1; i++) {
 | 
			
		||||
 | 
			
		||||
					// Iterate elements in the NodeList, return the first visible
 | 
			
		||||
					if (modal.isElementVisible(nodeList[i])) {
 | 
			
		||||
						return nodeList[i];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				return nodeList[0];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Return the last visible element of a nodeList
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param nodeList The nodelist to parse
 | 
			
		||||
		 * @return {Node|null} Returns a specific node or null if no element found
 | 
			
		||||
		 */
 | 
			
		||||
		getLastElementVisible: function (nodeList) {
 | 
			
		||||
			var nodeListLength = nodeList.length;
 | 
			
		||||
			var lastTabbableElement = nodeList[nodeListLength - 1];
 | 
			
		||||
 | 
			
		||||
			// If the last item is not visible
 | 
			
		||||
			if (!modal.isElementVisible(lastTabbableElement)) {
 | 
			
		||||
				for (var i = nodeListLength - 1; i >= 0; i--) {
 | 
			
		||||
 | 
			
		||||
					// Iterate elements in the NodeList, return the first visible
 | 
			
		||||
					if (modal.isElementVisible(nodeList[i])) {
 | 
			
		||||
						return nodeList[i];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				return lastTabbableElement;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Convenience function to check if an element is visible
 | 
			
		||||
		 *
 | 
			
		||||
		 * Test idea taken from jQuery 1.3.2 source code
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param element {Node} element to test
 | 
			
		||||
		 * @return {boolean} is the element visible or not
 | 
			
		||||
		 */
 | 
			
		||||
		isElementVisible: function (element) {
 | 
			
		||||
			return !(element.offsetWidth === 0 && element.offsetHeight === 0);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Mark modal as active
 | 
			
		||||
		 * @param element {Node} element to set active
 | 
			
		||||
		 */
 | 
			
		||||
		setActive: function (element) {
 | 
			
		||||
			modal.addClass(element, 'is-active');
 | 
			
		||||
			modal.activeElement = element;
 | 
			
		||||
 | 
			
		||||
			// Update aria-hidden
 | 
			
		||||
			modal.activeElement.setAttribute('aria-hidden', 'false');
 | 
			
		||||
 | 
			
		||||
			// Set the focus to the modal
 | 
			
		||||
			modal.setFocus(element.id);
 | 
			
		||||
 | 
			
		||||
			// Fire an event
 | 
			
		||||
			modal.trigger('cssmodal:show', modal.activeElement);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Unset previous active modal
 | 
			
		||||
		 * @param isStacked          {boolean} `true` if element is stacked above another
 | 
			
		||||
		 * @param shouldNotBeStacked {boolean} `true` if next element should be stacked
 | 
			
		||||
		 */
 | 
			
		||||
		unsetActive: function (isStacked, shouldNotBeStacked) {
 | 
			
		||||
			modal.removeClass(document.documentElement, 'has-overlay');
 | 
			
		||||
 | 
			
		||||
			if (modal.activeElement) {
 | 
			
		||||
				modal.removeClass(modal.activeElement, 'is-active');
 | 
			
		||||
 | 
			
		||||
				// Fire an event
 | 
			
		||||
				modal.trigger('cssmodal:hide', modal.activeElement);
 | 
			
		||||
 | 
			
		||||
				// Update aria-hidden
 | 
			
		||||
				modal.activeElement.setAttribute('aria-hidden', 'true');
 | 
			
		||||
 | 
			
		||||
				// Unfocus
 | 
			
		||||
				modal.removeFocus();
 | 
			
		||||
 | 
			
		||||
				// Make modal stacked if needed
 | 
			
		||||
				if (isStacked && !shouldNotBeStacked) {
 | 
			
		||||
					modal.stackModal(modal.activeElement);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// If there are any stacked elements
 | 
			
		||||
				if (!isStacked && modal.stackedElements.length > 0) {
 | 
			
		||||
					modal.unstackModal();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Reset active element
 | 
			
		||||
				modal.activeElement = null;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Stackable modal
 | 
			
		||||
		 * @param stackableModal {node} element to be stacked
 | 
			
		||||
		 */
 | 
			
		||||
		stackModal: function (stackableModal) {
 | 
			
		||||
			modal.addClass(stackableModal, 'is-stacked');
 | 
			
		||||
 | 
			
		||||
			// Set modal as stacked
 | 
			
		||||
			modal.stackedElements.push(modal.activeElement);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Reactivate stacked modal
 | 
			
		||||
		 */
 | 
			
		||||
		unstackModal: function () {
 | 
			
		||||
			var stackedCount = modal.stackedElements.length;
 | 
			
		||||
			var lastStacked = modal.stackedElements[stackedCount - 1];
 | 
			
		||||
 | 
			
		||||
			modal.removeClass(lastStacked, 'is-stacked');
 | 
			
		||||
 | 
			
		||||
			// Set hash to modal, activates the modal automatically
 | 
			
		||||
			global.location.hash = lastStacked.id;
 | 
			
		||||
 | 
			
		||||
			// Remove modal from stackedElements array
 | 
			
		||||
			modal.stackedElements.splice(stackedCount - 1, 1);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * When displaying modal, prevent background from scrolling
 | 
			
		||||
		 * @param  {Object} event The incoming hashChange event
 | 
			
		||||
		 * @return {void}
 | 
			
		||||
		 */
 | 
			
		||||
		mainHandler: function (event, noHash) {
 | 
			
		||||
			var hash = global.location.hash.replace('#', '');
 | 
			
		||||
			var index = 0;
 | 
			
		||||
			var tmp = [];
 | 
			
		||||
			var modalElement;
 | 
			
		||||
			var modalChild;
 | 
			
		||||
 | 
			
		||||
			// JS-only: no hash present
 | 
			
		||||
			if (noHash) {
 | 
			
		||||
				hash = event.currentTarget.getAttribute('href').replace('#', '');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			modalElement = document.getElementById(hash);
 | 
			
		||||
 | 
			
		||||
			// Check if the hash contains an index
 | 
			
		||||
			if (hash.indexOf('/') !== -1) {
 | 
			
		||||
				tmp = hash.split('/');
 | 
			
		||||
				index = tmp.pop();
 | 
			
		||||
				hash = tmp.join('/');
 | 
			
		||||
 | 
			
		||||
				// Remove the index from the hash...
 | 
			
		||||
				modalElement = document.getElementById(hash);
 | 
			
		||||
 | 
			
		||||
				// ... and store the index as a number on the element to
 | 
			
		||||
				// make it accessible for plugins
 | 
			
		||||
				if (!modalElement) {
 | 
			
		||||
					throw new Error('ReferenceError: element "' + hash + '" does not exist!');
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				modalElement.index = (1 * index);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// If the hash element exists
 | 
			
		||||
			if (modalElement) {
 | 
			
		||||
 | 
			
		||||
				// Polyfill to prevent the default behavior of events
 | 
			
		||||
				try {
 | 
			
		||||
					event.preventDefault();
 | 
			
		||||
				} catch (ex) {
 | 
			
		||||
					event.returnValue = false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Get first element in selected element
 | 
			
		||||
				modalChild = modalElement.children[0];
 | 
			
		||||
 | 
			
		||||
				// When we deal with a modal and body-class `has-overlay` is not set
 | 
			
		||||
				if (modalChild && modalChild.className.match(/modal-inner/)) {
 | 
			
		||||
 | 
			
		||||
					// Make previous element stackable if it is not the same modal
 | 
			
		||||
					modal.unsetActive(
 | 
			
		||||
						!modal.hasClass(modalElement, 'is-active'),
 | 
			
		||||
						(modalElement.getAttribute('data-stackable') === 'false')
 | 
			
		||||
					);
 | 
			
		||||
 | 
			
		||||
					// Set an html class to prevent scrolling
 | 
			
		||||
					modal.addClass(document.documentElement, 'has-overlay');
 | 
			
		||||
 | 
			
		||||
					// Set scroll position for modal
 | 
			
		||||
					modal._currentScrollPositionY = global.scrollY;
 | 
			
		||||
					modal._currentScrollPositionX = global.scrollX;
 | 
			
		||||
 | 
			
		||||
					// Mark the active element
 | 
			
		||||
					modal.setActive(modalElement);
 | 
			
		||||
					modal.activeElement._noHash = noHash;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				// If activeElement is already defined, delete it
 | 
			
		||||
				modal.unsetActive();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Inject iframes
 | 
			
		||||
		 */
 | 
			
		||||
		injectIframes: function () {
 | 
			
		||||
			var iframes = document.querySelectorAll('[data-iframe-src]');
 | 
			
		||||
			var iframe;
 | 
			
		||||
			var i = 0;
 | 
			
		||||
 | 
			
		||||
			for (; i < iframes.length; i++) {
 | 
			
		||||
				iframe = document.createElement('iframe');
 | 
			
		||||
 | 
			
		||||
				iframe.src = iframes[i].getAttribute('data-iframe-src');
 | 
			
		||||
				iframe.setAttribute('webkitallowfullscreen', true);
 | 
			
		||||
				iframe.setAttribute('mozallowfullscreen', true);
 | 
			
		||||
				iframe.setAttribute('allowfullscreen', true);
 | 
			
		||||
 | 
			
		||||
				iframes[i].appendChild(iframe);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Listen to all relevant events
 | 
			
		||||
		 * @return {void}
 | 
			
		||||
		 */
 | 
			
		||||
		init: function () {
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Hide overlay when ESC is pressed
 | 
			
		||||
			 */
 | 
			
		||||
			this.on('keyup', document, function (event) {
 | 
			
		||||
				var hash = global.location.hash.replace('#', '');
 | 
			
		||||
 | 
			
		||||
				// If key ESC is pressed
 | 
			
		||||
				if (event.keyCode === 27) {
 | 
			
		||||
					if (modal.activeElement && hash === modal.activeElement.id) {
 | 
			
		||||
						global.location.hash = '!';
 | 
			
		||||
					} else {
 | 
			
		||||
						modal.unsetActive();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (modal.lastActive) {
 | 
			
		||||
						return false;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Unfocus
 | 
			
		||||
					modal.removeFocus();
 | 
			
		||||
				}
 | 
			
		||||
			}, false);
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * Trigger main handler on click if hash is deactivated
 | 
			
		||||
			 */
 | 
			
		||||
			this.on('click', document.querySelectorAll('[data-cssmodal-nohash]'), function (event) {
 | 
			
		||||
				modal.mainHandler(event, true);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			// And close modal without hash
 | 
			
		||||
			this.on('click', document.querySelectorAll('.modal-close'), function (event) {
 | 
			
		||||
				if (modal.activeElement._noHash){
 | 
			
		||||
					modal.mainHandler(event, true);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Trigger main handler on load and hashchange
 | 
			
		||||
			 */
 | 
			
		||||
			this.on('hashchange', global, modal.mainHandler);
 | 
			
		||||
			this.on('load', global, modal.mainHandler);
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * Prevent scrolling when modal is active
 | 
			
		||||
			 * @return {void}
 | 
			
		||||
			 */
 | 
			
		||||
			global.onscroll = global.onmousewheel = function () {
 | 
			
		||||
				if (document.documentElement.className.match(/has-overlay/)) {
 | 
			
		||||
					global.scrollTo(modal._currentScrollPositionX, modal._currentScrollPositionY);
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * Inject iframes
 | 
			
		||||
			 */
 | 
			
		||||
			modal.injectIframes();
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * AMD, module loader, global registration
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	// Expose modal for loaders that implement the Node module pattern.
 | 
			
		||||
	if (typeof module === 'object' && module && typeof module.exports === 'object') {
 | 
			
		||||
		module.exports = modal;
 | 
			
		||||
 | 
			
		||||
	// Register as an AMD module
 | 
			
		||||
	} else if (typeof define === 'function' && define.amd) {
 | 
			
		||||
		define('CSSModal', [], function () {
 | 
			
		||||
 | 
			
		||||
			// We use jQuery if the browser doesn't support CustomEvents
 | 
			
		||||
			if (!global.CustomEvent && !$) {
 | 
			
		||||
				throw new Error('This browser doesn\'t support CustomEvent - please include jQuery.');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			modal.init();
 | 
			
		||||
 | 
			
		||||
			return modal;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// Export CSSModal into global space
 | 
			
		||||
	} else if (typeof global === 'object' && typeof global.document === 'object') {
 | 
			
		||||
		global.CSSModal = modal;
 | 
			
		||||
		modal.init();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}(window, window.jQuery));
 | 
			
		||||
							
								
								
									
										46
									
								
								Seenginx/wwwroot/js/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Seenginx/wwwroot/js/ui.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
(function (window, document) {
 | 
			
		||||
 | 
			
		||||
    var layout   = document.getElementById('layout'),
 | 
			
		||||
        menu     = document.getElementById('menu'),
 | 
			
		||||
        menuLink = document.getElementById('menuLink'),
 | 
			
		||||
        content  = document.getElementById('main');
 | 
			
		||||
 | 
			
		||||
    function toggleClass(element, className) {
 | 
			
		||||
        var classes = element.className.split(/\s+/),
 | 
			
		||||
            length = classes.length,
 | 
			
		||||
            i = 0;
 | 
			
		||||
 | 
			
		||||
        for(; i < length; i++) {
 | 
			
		||||
          if (classes[i] === className) {
 | 
			
		||||
            classes.splice(i, 1);
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // The className is not found
 | 
			
		||||
        if (length === classes.length) {
 | 
			
		||||
            classes.push(className);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element.className = classes.join(' ');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function toggleAll(e) {
 | 
			
		||||
        var active = 'active';
 | 
			
		||||
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        toggleClass(layout, active);
 | 
			
		||||
        toggleClass(menu, active);
 | 
			
		||||
        toggleClass(menuLink, active);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    menuLink.onclick = function (e) {
 | 
			
		||||
        toggleAll(e);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    content.onclick = function(e) {
 | 
			
		||||
        if (menu.className.indexOf('active') !== -1) {
 | 
			
		||||
            toggleAll(e);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}(this, this.document));
 | 
			
		||||
		Reference in New Issue
	
	Block a user