├── .gitattributes ├── .gitignore ├── DotNetBlog.sln ├── Nuget.config ├── README.md ├── global.json └── src ├── DotNetBlog.Admin ├── .babelrc ├── actions │ └── index.js ├── components │ ├── bootstrap │ │ └── formgroup.jsx │ ├── contentheader.jsx │ ├── editor.jsx │ ├── form.jsx │ ├── index.jsx │ ├── loadingbutton.jsx │ ├── pager.jsx │ └── spinner.jsx ├── consts │ └── index.js ├── img │ ├── boxed-bg.jpg │ ├── boxed-bg.png │ └── icons.png ├── index.jsx ├── jsconfig.json ├── package.json ├── reducers │ └── index.js ├── resources │ └── index.js ├── server.js ├── services │ ├── api.js │ ├── dialog.js │ └── index.js ├── store │ └── index.js ├── styles │ ├── AdminLTE.css │ ├── _all-skins.css │ └── app.css ├── typings │ ├── globals │ │ ├── async │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── lodash │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── react-bootstrap │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── react-redux │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── react-router │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── react │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── redux-thunk │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── redux │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ └── toastr │ │ │ ├── index.d.ts │ │ │ └── typings.json │ └── index.d.ts ├── views │ ├── app.jsx │ ├── config │ │ ├── advanceconfig.jsx │ │ ├── basicconfig.jsx │ │ ├── commentconfig.jsx │ │ └── emailconfig.jsx │ ├── content │ │ ├── categorylist.jsx │ │ ├── commentlist.jsx │ │ ├── modifycategory.jsx │ │ ├── modifypage.jsx │ │ ├── modifytag.jsx │ │ ├── modifytopic.jsx │ │ ├── modifytopicsetting.jsx │ │ ├── pagelist.jsx │ │ ├── replycomment.jsx │ │ ├── taglist.jsx │ │ └── topiclist.jsx │ ├── dashboard │ │ ├── dashboard.jsx │ │ ├── quickpost.jsx │ │ ├── recentcomment.jsx │ │ ├── statistics.jsx │ │ └── topicdraft.jsx │ ├── user │ │ └── profile.jsx │ └── widget │ │ ├── editbasic.jsx │ │ ├── editcategory.jsx │ │ ├── editrecentcomment.jsx │ │ ├── editrecenttopic.jsx │ │ ├── edittag.jsx │ │ ├── widgetinfo.jsx │ │ ├── widgetitem.jsx │ │ └── widgets.jsx └── webpack.config.js ├── DotNetBlog.Core ├── ClientManager.cs ├── Data │ ├── BlogContext.cs │ └── Mappings │ │ ├── CategoryMapping.cs │ │ ├── CategoryTopicMapping.cs │ │ ├── CommentMapping.cs │ │ ├── LinkMapping.cs │ │ ├── PageMapping.cs │ │ ├── SettingMapping.cs │ │ ├── TagMapping.cs │ │ ├── TagTopicMapping.cs │ │ ├── TopicMapping.cs │ │ ├── UserMapping.cs │ │ ├── UserTokenMapping.cs │ │ └── WidgetMapping.cs ├── DotNetBlog.Core.csproj ├── Entity │ ├── Category.cs │ ├── CategoryTopic.cs │ ├── Comment.cs │ ├── Link.cs │ ├── Page.cs │ ├── Setting.cs │ ├── Tag.cs │ ├── TagTopic.cs │ ├── Topic.cs │ ├── User.cs │ ├── UserToken.cs │ └── Widget.cs ├── Enums │ ├── CommentStatus.cs │ ├── PageStatus.cs │ ├── TopicStatus.cs │ └── WidgetType.cs ├── Extensions │ ├── BlogContextExtensions.cs │ ├── MemoryCacheExtensions.cs │ └── StringExtensions.cs ├── IServiceCollectionExtensions.cs ├── Model │ ├── Category │ │ ├── CategoryBasicModel.cs │ │ └── CategoryModel.cs │ ├── Comment │ │ ├── AddCommentModel.cs │ │ ├── CommentCountModel.cs │ │ ├── CommentItemModel.cs │ │ └── CommentModel.cs │ ├── Email │ │ ├── CommentEmailModel.cs │ │ └── TestEmailConfigModel.cs │ ├── Install │ │ └── InstallModel.cs │ ├── OperationResult.cs │ ├── Page │ │ ├── AddPageModel.cs │ │ ├── EditPageModel.cs │ │ ├── PageBasicModel.cs │ │ ├── PageCountModel.cs │ │ └── PageModel.cs │ ├── Setting │ │ └── SettingModel.cs │ ├── Statistics │ │ └── BlogStatisticsModel.cs │ ├── Tag │ │ └── TagModel.cs │ ├── Theme │ │ └── ThemeModel.cs │ ├── Topic │ │ ├── AddTopicModel.cs │ │ ├── EditTopicModel.cs │ │ ├── ITopicModel.cs │ │ ├── MonthStatisticsModel.cs │ │ ├── TopicBasicModel.cs │ │ ├── TopicCountModel.cs │ │ └── TopicModel.cs │ └── Widget │ │ ├── AvailableWidgetModel.cs │ │ ├── WidgetConfigModel.cs │ │ └── WidgetModel.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── Model │ │ ├── Setting │ │ │ ├── SettingModel.en-GB.resx │ │ │ └── SettingModel.zh-CN.resx │ │ └── Widget │ │ │ ├── WidgetConfigModelBase.en-GB.resx │ │ │ └── WidgetConfigModelBase.zh-CN.resx │ └── Service │ │ ├── AuthService.en-GB.resx │ │ ├── AuthService.zh-CN.resx │ │ ├── CategoryService.en-GB.resx │ │ ├── CategoryService.zh-CN.resx │ │ ├── CommentService.en-GB.resx │ │ ├── CommentService.zh-CN.resx │ │ ├── EmailService.en-GB.resx │ │ ├── EmailService.zh-CN.resx │ │ ├── InstallService.en-GB.resx │ │ ├── InstallService.zh-CN.resx │ │ ├── PageService.en-GB.resx │ │ ├── PageService.zh-CN.resx │ │ ├── TagService.en-GB.resx │ │ ├── TagService.zh-CN.resx │ │ ├── TopicService.en-GB.resx │ │ ├── TopicService.zh-CN.resx │ │ ├── UserService.en-GB.resx │ │ └── UserService.zh-CN.resx ├── Service │ ├── AuthService.cs │ ├── CategoryService.cs │ ├── CommentService.cs │ ├── EmailService.cs │ ├── InstallService.cs │ ├── PageService.cs │ ├── SettingService.cs │ ├── StatisticsService.cs │ ├── TagService.cs │ ├── ThemeService.cs │ ├── TopicService.cs │ ├── UserService.cs │ └── WidgetService.cs └── Utilities │ └── EncryptHelper.cs └── DotNetBlog.Web ├── Areas └── Api │ ├── Controllers │ ├── CategoryController.cs │ ├── CommentController.cs │ ├── ConfigController.cs │ ├── ControllerBase.cs │ ├── MyController.cs │ ├── PageController.cs │ ├── StatisticsController.cs │ ├── TagController.cs │ ├── TopicController.cs │ ├── UploadController.cs │ └── WidgetController.cs │ ├── Filters │ ├── ErrorHandlerFilter.cs │ ├── RequireLoginApiFilter.cs │ └── ValidateRequestApiFilter.cs │ └── Models │ ├── ApiResponse.cs │ ├── Category │ ├── RemoveCategoryModel.cs │ └── SaveCategoryModel.cs │ ├── Comment │ ├── BatchModel.cs │ ├── QueryCommentModel.cs │ └── ReplyCommentModel.cs │ ├── Config │ ├── AdvanceConfigModel.cs │ ├── BasicConfigModel.cs │ ├── CommentConfigModel.cs │ └── EmailConfigModel.cs │ ├── My │ └── EditMyInfoModel.cs │ ├── Page │ └── BatchModel.cs │ ├── Tag │ ├── DeleteTagModel.cs │ ├── QueryTagModel.cs │ └── SaveTagModel.cs │ ├── Topic │ ├── BatchModel.cs │ └── QueryTopicModel.cs │ ├── Upload │ └── UploadImageModel.cs │ └── Widget │ └── SaveWidgetModel.cs ├── AutoMapperConfig.cs ├── Controllers ├── AccountController.cs ├── AdminController.cs ├── ExceptionController.cs ├── HomeController.cs ├── InstallController.cs └── QuickActionController.cs ├── DotNetBlog.Web.csproj ├── Filters ├── ErrorHandleFilter.cs ├── RequireLoginFilter.cs └── ValidateRequestFilter.cs ├── Middlewares └── ClientManagerMiddleware.cs ├── NLog.config ├── Program.cs ├── Properties ├── PublishProfiles │ ├── publish-module.psm1 │ ├── release-publish.ps1 │ └── release.pubxml └── launchSettings.json ├── Resources ├── Areas │ ├── Controllers │ │ ├── ControllerBase.en-GB.resx │ │ ├── ControllerBase.zh-CN.resx │ │ ├── TopicController.en-GB.resx │ │ ├── TopicController.zh-CN.resx │ │ ├── UploadController.en-GB.resx │ │ └── UploadController.zh-CN.resx │ └── Filters │ │ ├── ErrorHandlerFilter.en-GB.resx │ │ ├── ErrorHandlerFilter.zh-CN.resx │ │ ├── RequireLoginApiFilter.en-GB.resx │ │ └── RequireLoginApiFilter.zh-CN.resx ├── Controllers │ ├── AccountController.en-GB.resx │ ├── AccountController.zh-CN.resx │ ├── HomeController.en-GB.resx │ ├── HomeController.zh-CN.resx │ ├── InstallController.en-GB.resx │ └── InstallController.zh-CN.resx ├── TagHelpers │ ├── PagerTagHelper.en-GB.resx │ └── PagerTagHelper.zh-CN.resx └── Views │ ├── Account │ ├── ChangePassword.en-GB.resx │ ├── ChangePassword.zh-CN.resx │ ├── Login.en-GB.resx │ └── Login.zh-CN.resx │ ├── Exception │ ├── Error.en-GB.resx │ ├── Error.zh-CN.resx │ ├── NotFound.en-GB.resx │ └── NotFound.zh-CN.resx │ ├── Home │ ├── Components │ │ ├── AdministrationWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── CategoryWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── MonthStatisticsWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── PageListNav │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── PageWidget │ │ │ └── Default.zh-CN.resx │ │ ├── RecentCommentWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── RecentTopicWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── SearchWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ ├── TagWidget │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ │ └── Widgets │ │ │ ├── Default.en-GB.resx │ │ │ └── Default.zh-CN.resx │ ├── Notice.en-GB.resx │ ├── Notice.zh-CN.resx │ ├── Page.en-GB.resx │ ├── Page.zh-CN.resx │ ├── Search.en-GB.resx │ ├── Search.zh-CN.resx │ ├── Topic.en-GB.resx │ ├── Topic.zh-CN.resx │ ├── _CommentList.en-GB.resx │ ├── _CommentList.zh-CN.resx │ ├── _Layout.en-GB.resx │ ├── _Layout.zh-CN.resx │ ├── _TopicList.en-GB.resx │ └── _TopicList.zh-CN.resx │ └── Install │ ├── Index.en-GB.resx │ └── Index.zh-CN.resx ├── Startup.cs ├── TagHelpers ├── BlogTitleTagHelper.cs ├── MarkdownTagHelper.cs ├── PageLinkTagHelper.cs ├── PagerTagHelper.cs ├── ThemeUrlResolutionTagHelper.cs ├── TopicLinkTagHelper.cs └── VisibleTagHelper.cs ├── Themes └── default │ ├── Account │ ├── ChangePassword.cshtml │ ├── Login.cshtml │ ├── _Layout.cshtml │ └── _ViewImports.cshtml │ ├── Admin │ └── Index.cshtml │ ├── Exception │ ├── Error.cshtml │ ├── NotFound.cshtml │ └── _Layout.cshtml │ ├── Home │ ├── Category.cshtml │ ├── Components │ │ ├── AdministrationWidget │ │ │ └── Default.cshtml │ │ ├── CategoryWidget │ │ │ └── Default.cshtml │ │ ├── MonthStatisticsWidget │ │ │ └── Default.cshtml │ │ ├── PageListNav │ │ │ └── Default.cshtml │ │ ├── PageWidget │ │ │ └── Default.cshtml │ │ ├── RecentCommentWidget │ │ │ └── Default.cshtml │ │ ├── RecentTopicWidget │ │ │ └── Default.cshtml │ │ ├── SearchWidget │ │ │ └── Default.cshtml │ │ ├── TagWidget │ │ │ └── Default.cshtml │ │ ├── Widgets │ │ │ └── Default.cshtml │ │ └── _ViewImports.cshtml │ ├── Index.cshtml │ ├── Month.cshtml │ ├── Notice.cshtml │ ├── Page.cshtml │ ├── Search.cshtml │ ├── Tag.cshtml │ ├── Topic.cshtml │ ├── _CommentList.cshtml │ ├── _Layout.cshtml │ ├── _TopicList.cshtml │ └── _ViewImports.cshtml │ ├── Install │ └── Index.cshtml │ ├── _ViewImports.cshtml │ ├── _ViewStart.cshtml │ └── theme.json ├── ViewComponents ├── PageListNav.cs └── Widgets.cs ├── ViewEngines └── ThemeViewEngine.cs ├── ViewModels ├── Account │ ├── ChangePasswordModel.cs │ ├── ChangePasswordViewModel.cs │ ├── LoginModel.cs │ └── LoginViewModel.cs ├── Exception │ └── ErrorViewModel.cs ├── Home │ ├── CategoryPageViewModel.cs │ ├── CommentFormModel.cs │ ├── CommentListViewModel.cs │ ├── IndexPageViewModel.cs │ ├── MonthPageViewModel.cs │ ├── NoticePageViewModel.cs │ ├── SearchPageViewModel.cs │ ├── TagPageViewModel.cs │ ├── TopicListModel.cs │ └── TopicPageViewModel.cs └── Install │ └── IndexViewModel.cs ├── Widgets ├── AdministrationWidget.cs ├── CategoryWidget.cs ├── MonthStatisticsWidget.cs ├── PageWidget.cs ├── RecentCommentWidget.cs ├── RecentTopicWidget.cs ├── SearchWidget.cs └── TagWidget.cs ├── config.json ├── runtimeconfig.template.json ├── web.config └── wwwroot ├── images ├── carrow.png └── widget │ ├── Administration.png │ ├── Category.png │ ├── MonthStatistics.png │ ├── Page.png │ ├── RecentComment.png │ ├── RecentTopic.png │ ├── Search.png │ └── Tag.png ├── lib ├── adminlte │ ├── AdminLTE.css │ └── _all-skins.css ├── editor.md │ ├── css │ │ ├── editormd.css │ │ ├── editormd.logo.css │ │ ├── editormd.logo.min.css │ │ ├── editormd.min.css │ │ ├── editormd.preview.css │ │ └── editormd.preview.min.css │ ├── editormd.js │ ├── editormd.min.js │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── editormd-logo.eot │ │ ├── editormd-logo.svg │ │ ├── editormd-logo.ttf │ │ ├── editormd-logo.woff │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── images │ │ ├── loading.gif │ │ ├── loading@2x.gif │ │ ├── loading@3x.gif │ │ └── logos │ │ │ ├── editormd-favicon-16x16.ico │ │ │ ├── editormd-favicon-24x24.ico │ │ │ ├── editormd-favicon-32x32.ico │ │ │ ├── editormd-favicon-48x48.ico │ │ │ ├── editormd-favicon-64x64.ico │ │ │ ├── editormd-logo-114x114.png │ │ │ ├── editormd-logo-120x120.png │ │ │ ├── editormd-logo-144x144.png │ │ │ ├── editormd-logo-16x16.png │ │ │ ├── editormd-logo-180x180.png │ │ │ ├── editormd-logo-240x240.png │ │ │ ├── editormd-logo-24x24.png │ │ │ ├── editormd-logo-320x320.png │ │ │ ├── editormd-logo-32x32.png │ │ │ ├── editormd-logo-48x48.png │ │ │ ├── editormd-logo-57x57.png │ │ │ ├── editormd-logo-64x64.png │ │ │ ├── editormd-logo-72x72.png │ │ │ ├── editormd-logo-96x96.png │ │ │ └── vi.png │ ├── languages │ │ ├── en.js │ │ └── zh-tw.js │ ├── lib │ │ ├── codemirror │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── addon │ │ │ │ ├── comment │ │ │ │ │ ├── comment.js │ │ │ │ │ └── continuecomment.js │ │ │ │ ├── dialog │ │ │ │ │ ├── dialog.css │ │ │ │ │ └── dialog.js │ │ │ │ ├── display │ │ │ │ │ ├── fullscreen.css │ │ │ │ │ ├── fullscreen.js │ │ │ │ │ ├── panel.js │ │ │ │ │ ├── placeholder.js │ │ │ │ │ └── rulers.js │ │ │ │ ├── edit │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ ├── closetag.js │ │ │ │ │ ├── continuelist.js │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ ├── matchtags.js │ │ │ │ │ └── trailingspace.js │ │ │ │ ├── fold │ │ │ │ │ ├── brace-fold.js │ │ │ │ │ ├── comment-fold.js │ │ │ │ │ ├── foldcode.js │ │ │ │ │ ├── foldgutter.css │ │ │ │ │ ├── foldgutter.js │ │ │ │ │ ├── indent-fold.js │ │ │ │ │ ├── markdown-fold.js │ │ │ │ │ └── xml-fold.js │ │ │ │ ├── hint │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ ├── css-hint.js │ │ │ │ │ ├── html-hint.js │ │ │ │ │ ├── javascript-hint.js │ │ │ │ │ ├── show-hint.css │ │ │ │ │ ├── show-hint.js │ │ │ │ │ ├── sql-hint.js │ │ │ │ │ └── xml-hint.js │ │ │ │ ├── lint │ │ │ │ │ ├── coffeescript-lint.js │ │ │ │ │ ├── css-lint.js │ │ │ │ │ ├── javascript-lint.js │ │ │ │ │ ├── json-lint.js │ │ │ │ │ ├── lint.css │ │ │ │ │ ├── lint.js │ │ │ │ │ └── yaml-lint.js │ │ │ │ ├── merge │ │ │ │ │ ├── merge.css │ │ │ │ │ └── merge.js │ │ │ │ ├── mode │ │ │ │ │ ├── loadmode.js │ │ │ │ │ ├── multiplex.js │ │ │ │ │ ├── multiplex_test.js │ │ │ │ │ ├── overlay.js │ │ │ │ │ └── simple.js │ │ │ │ ├── runmode │ │ │ │ │ ├── colorize.js │ │ │ │ │ ├── runmode-standalone.js │ │ │ │ │ ├── runmode.js │ │ │ │ │ └── runmode.node.js │ │ │ │ ├── scroll │ │ │ │ │ ├── annotatescrollbar.js │ │ │ │ │ ├── scrollpastend.js │ │ │ │ │ ├── simplescrollbars.css │ │ │ │ │ └── simplescrollbars.js │ │ │ │ ├── search │ │ │ │ │ ├── match-highlighter.js │ │ │ │ │ ├── matchesonscrollbar.css │ │ │ │ │ ├── matchesonscrollbar.js │ │ │ │ │ ├── search.js │ │ │ │ │ └── searchcursor.js │ │ │ │ ├── selection │ │ │ │ │ ├── active-line.js │ │ │ │ │ ├── mark-selection.js │ │ │ │ │ └── selection-pointer.js │ │ │ │ ├── tern │ │ │ │ │ ├── tern.css │ │ │ │ │ ├── tern.js │ │ │ │ │ └── worker.js │ │ │ │ └── wrap │ │ │ │ │ └── hardwrap.js │ │ │ ├── addons.min.js │ │ │ ├── bower.json │ │ │ ├── codemirror.min.css │ │ │ ├── codemirror.min.js │ │ │ ├── lib │ │ │ │ ├── codemirror.css │ │ │ │ └── codemirror.js │ │ │ ├── mode │ │ │ │ ├── apl │ │ │ │ │ ├── apl.js │ │ │ │ │ └── index.html │ │ │ │ ├── asterisk │ │ │ │ │ ├── asterisk.js │ │ │ │ │ └── index.html │ │ │ │ ├── clike │ │ │ │ │ ├── clike.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── scala.html │ │ │ │ ├── clojure │ │ │ │ │ ├── clojure.js │ │ │ │ │ └── index.html │ │ │ │ ├── cobol │ │ │ │ │ ├── cobol.js │ │ │ │ │ └── index.html │ │ │ │ ├── coffeescript │ │ │ │ │ ├── coffeescript.js │ │ │ │ │ └── index.html │ │ │ │ ├── commonlisp │ │ │ │ │ ├── commonlisp.js │ │ │ │ │ └── index.html │ │ │ │ ├── css │ │ │ │ │ ├── css.js │ │ │ │ │ ├── index.html │ │ │ │ │ ├── less.html │ │ │ │ │ ├── less_test.js │ │ │ │ │ ├── scss.html │ │ │ │ │ ├── scss_test.js │ │ │ │ │ └── test.js │ │ │ │ ├── cypher │ │ │ │ │ ├── cypher.js │ │ │ │ │ └── index.html │ │ │ │ ├── d │ │ │ │ │ ├── d.js │ │ │ │ │ └── index.html │ │ │ │ ├── dart │ │ │ │ │ ├── dart.js │ │ │ │ │ └── index.html │ │ │ │ ├── diff │ │ │ │ │ ├── diff.js │ │ │ │ │ └── index.html │ │ │ │ ├── django │ │ │ │ │ ├── django.js │ │ │ │ │ └── index.html │ │ │ │ ├── dockerfile │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ └── index.html │ │ │ │ ├── dtd │ │ │ │ │ ├── dtd.js │ │ │ │ │ └── index.html │ │ │ │ ├── dylan │ │ │ │ │ ├── dylan.js │ │ │ │ │ └── index.html │ │ │ │ ├── ebnf │ │ │ │ │ ├── ebnf.js │ │ │ │ │ └── index.html │ │ │ │ ├── ecl │ │ │ │ │ ├── ecl.js │ │ │ │ │ └── index.html │ │ │ │ ├── eiffel │ │ │ │ │ ├── eiffel.js │ │ │ │ │ └── index.html │ │ │ │ ├── erlang │ │ │ │ │ ├── erlang.js │ │ │ │ │ └── index.html │ │ │ │ ├── forth │ │ │ │ │ ├── forth.js │ │ │ │ │ └── index.html │ │ │ │ ├── fortran │ │ │ │ │ ├── fortran.js │ │ │ │ │ └── index.html │ │ │ │ ├── gas │ │ │ │ │ ├── gas.js │ │ │ │ │ └── index.html │ │ │ │ ├── gfm │ │ │ │ │ ├── gfm.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── test.js │ │ │ │ ├── gherkin │ │ │ │ │ ├── gherkin.js │ │ │ │ │ └── index.html │ │ │ │ ├── go │ │ │ │ │ ├── go.js │ │ │ │ │ └── index.html │ │ │ │ ├── groovy │ │ │ │ │ ├── groovy.js │ │ │ │ │ └── index.html │ │ │ │ ├── haml │ │ │ │ │ ├── haml.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── test.js │ │ │ │ ├── haskell │ │ │ │ │ ├── haskell.js │ │ │ │ │ └── index.html │ │ │ │ ├── haxe │ │ │ │ │ ├── haxe.js │ │ │ │ │ └── index.html │ │ │ │ ├── htmlembedded │ │ │ │ │ ├── htmlembedded.js │ │ │ │ │ └── index.html │ │ │ │ ├── htmlmixed │ │ │ │ │ ├── htmlmixed.js │ │ │ │ │ └── index.html │ │ │ │ ├── http │ │ │ │ │ ├── http.js │ │ │ │ │ └── index.html │ │ │ │ ├── idl │ │ │ │ │ ├── idl.js │ │ │ │ │ └── index.html │ │ │ │ ├── index.html │ │ │ │ ├── jade │ │ │ │ │ ├── index.html │ │ │ │ │ └── jade.js │ │ │ │ ├── javascript │ │ │ │ │ ├── index.html │ │ │ │ │ ├── javascript.js │ │ │ │ │ ├── json-ld.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── typescript.html │ │ │ │ ├── jinja2 │ │ │ │ │ ├── index.html │ │ │ │ │ └── jinja2.js │ │ │ │ ├── julia │ │ │ │ │ ├── index.html │ │ │ │ │ └── julia.js │ │ │ │ ├── kotlin │ │ │ │ │ ├── index.html │ │ │ │ │ └── kotlin.js │ │ │ │ ├── livescript │ │ │ │ │ ├── index.html │ │ │ │ │ └── livescript.js │ │ │ │ ├── lua │ │ │ │ │ ├── index.html │ │ │ │ │ └── lua.js │ │ │ │ ├── markdown │ │ │ │ │ ├── index.html │ │ │ │ │ ├── markdown.js │ │ │ │ │ └── test.js │ │ │ │ ├── meta.js │ │ │ │ ├── mirc │ │ │ │ │ ├── index.html │ │ │ │ │ └── mirc.js │ │ │ │ ├── mllike │ │ │ │ │ ├── index.html │ │ │ │ │ └── mllike.js │ │ │ │ ├── modelica │ │ │ │ │ ├── index.html │ │ │ │ │ └── modelica.js │ │ │ │ ├── nginx │ │ │ │ │ ├── index.html │ │ │ │ │ └── nginx.js │ │ │ │ ├── ntriples │ │ │ │ │ ├── index.html │ │ │ │ │ └── ntriples.js │ │ │ │ ├── octave │ │ │ │ │ ├── index.html │ │ │ │ │ └── octave.js │ │ │ │ ├── pascal │ │ │ │ │ ├── index.html │ │ │ │ │ └── pascal.js │ │ │ │ ├── pegjs │ │ │ │ │ ├── index.html │ │ │ │ │ └── pegjs.js │ │ │ │ ├── perl │ │ │ │ │ ├── index.html │ │ │ │ │ └── perl.js │ │ │ │ ├── php │ │ │ │ │ ├── index.html │ │ │ │ │ ├── php.js │ │ │ │ │ └── test.js │ │ │ │ ├── pig │ │ │ │ │ ├── index.html │ │ │ │ │ └── pig.js │ │ │ │ ├── properties │ │ │ │ │ ├── index.html │ │ │ │ │ └── properties.js │ │ │ │ ├── puppet │ │ │ │ │ ├── index.html │ │ │ │ │ └── puppet.js │ │ │ │ ├── python │ │ │ │ │ ├── index.html │ │ │ │ │ └── python.js │ │ │ │ ├── q │ │ │ │ │ ├── index.html │ │ │ │ │ └── q.js │ │ │ │ ├── r │ │ │ │ │ ├── index.html │ │ │ │ │ └── r.js │ │ │ │ ├── rpm │ │ │ │ │ ├── changes │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── index.html │ │ │ │ │ └── rpm.js │ │ │ │ ├── rst │ │ │ │ │ ├── index.html │ │ │ │ │ └── rst.js │ │ │ │ ├── ruby │ │ │ │ │ ├── index.html │ │ │ │ │ ├── ruby.js │ │ │ │ │ └── test.js │ │ │ │ ├── rust │ │ │ │ │ ├── index.html │ │ │ │ │ └── rust.js │ │ │ │ ├── sass │ │ │ │ │ ├── index.html │ │ │ │ │ └── sass.js │ │ │ │ ├── scheme │ │ │ │ │ ├── index.html │ │ │ │ │ └── scheme.js │ │ │ │ ├── shell │ │ │ │ │ ├── index.html │ │ │ │ │ ├── shell.js │ │ │ │ │ └── test.js │ │ │ │ ├── sieve │ │ │ │ │ ├── index.html │ │ │ │ │ └── sieve.js │ │ │ │ ├── slim │ │ │ │ │ ├── index.html │ │ │ │ │ ├── slim.js │ │ │ │ │ └── test.js │ │ │ │ ├── smalltalk │ │ │ │ │ ├── index.html │ │ │ │ │ └── smalltalk.js │ │ │ │ ├── smarty │ │ │ │ │ ├── index.html │ │ │ │ │ └── smarty.js │ │ │ │ ├── smartymixed │ │ │ │ │ ├── index.html │ │ │ │ │ └── smartymixed.js │ │ │ │ ├── solr │ │ │ │ │ ├── index.html │ │ │ │ │ └── solr.js │ │ │ │ ├── soy │ │ │ │ │ ├── index.html │ │ │ │ │ └── soy.js │ │ │ │ ├── sparql │ │ │ │ │ ├── index.html │ │ │ │ │ └── sparql.js │ │ │ │ ├── spreadsheet │ │ │ │ │ ├── index.html │ │ │ │ │ └── spreadsheet.js │ │ │ │ ├── sql │ │ │ │ │ ├── index.html │ │ │ │ │ └── sql.js │ │ │ │ ├── stex │ │ │ │ │ ├── index.html │ │ │ │ │ ├── stex.js │ │ │ │ │ └── test.js │ │ │ │ ├── stylus │ │ │ │ │ ├── index.html │ │ │ │ │ └── stylus.js │ │ │ │ ├── tcl │ │ │ │ │ ├── index.html │ │ │ │ │ └── tcl.js │ │ │ │ ├── textile │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── textile.js │ │ │ │ ├── tiddlywiki │ │ │ │ │ ├── index.html │ │ │ │ │ ├── tiddlywiki.css │ │ │ │ │ └── tiddlywiki.js │ │ │ │ ├── tiki │ │ │ │ │ ├── index.html │ │ │ │ │ ├── tiki.css │ │ │ │ │ └── tiki.js │ │ │ │ ├── toml │ │ │ │ │ ├── index.html │ │ │ │ │ └── toml.js │ │ │ │ ├── tornado │ │ │ │ │ ├── index.html │ │ │ │ │ └── tornado.js │ │ │ │ ├── turtle │ │ │ │ │ ├── index.html │ │ │ │ │ └── turtle.js │ │ │ │ ├── vb │ │ │ │ │ ├── index.html │ │ │ │ │ └── vb.js │ │ │ │ ├── vbscript │ │ │ │ │ ├── index.html │ │ │ │ │ └── vbscript.js │ │ │ │ ├── velocity │ │ │ │ │ ├── index.html │ │ │ │ │ └── velocity.js │ │ │ │ ├── verilog │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── verilog.js │ │ │ │ ├── xml │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── xml.js │ │ │ │ ├── xquery │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── xquery.js │ │ │ │ ├── yaml │ │ │ │ │ ├── index.html │ │ │ │ │ └── yaml.js │ │ │ │ └── z80 │ │ │ │ │ ├── index.html │ │ │ │ │ └── z80.js │ │ │ ├── modes.min.js │ │ │ ├── package.json │ │ │ └── theme │ │ │ │ ├── 3024-day.css │ │ │ │ ├── 3024-night.css │ │ │ │ ├── ambiance-mobile.css │ │ │ │ ├── ambiance.css │ │ │ │ ├── base16-dark.css │ │ │ │ ├── base16-light.css │ │ │ │ ├── blackboard.css │ │ │ │ ├── cobalt.css │ │ │ │ ├── colorforth.css │ │ │ │ ├── eclipse.css │ │ │ │ ├── elegant.css │ │ │ │ ├── erlang-dark.css │ │ │ │ ├── lesser-dark.css │ │ │ │ ├── mbo.css │ │ │ │ ├── mdn-like.css │ │ │ │ ├── midnight.css │ │ │ │ ├── monokai.css │ │ │ │ ├── neat.css │ │ │ │ ├── neo.css │ │ │ │ ├── night.css │ │ │ │ ├── paraiso-dark.css │ │ │ │ ├── paraiso-light.css │ │ │ │ ├── pastel-on-dark.css │ │ │ │ ├── rubyblue.css │ │ │ │ ├── solarized.css │ │ │ │ ├── the-matrix.css │ │ │ │ ├── tomorrow-night-bright.css │ │ │ │ ├── tomorrow-night-eighties.css │ │ │ │ ├── twilight.css │ │ │ │ ├── vibrant-ink.css │ │ │ │ ├── xq-dark.css │ │ │ │ ├── xq-light.css │ │ │ │ └── zenburn.css │ │ ├── flowchart.min.js │ │ ├── jquery.flowchart.min.js │ │ ├── marked.min.js │ │ ├── prettify.min.js │ │ ├── raphael.min.js │ │ ├── sequence-diagram.min.js │ │ └── underscore.min.js │ └── plugins │ │ ├── code-block-dialog │ │ └── code-block-dialog.js │ │ ├── emoji-dialog │ │ ├── emoji-dialog.js │ │ └── emoji.json │ │ ├── goto-line-dialog │ │ └── goto-line-dialog.js │ │ ├── help-dialog │ │ ├── help-dialog.js │ │ └── help.md │ │ ├── html-entities-dialog │ │ ├── html-entities-dialog.js │ │ └── html-entities.json │ │ ├── image-dialog │ │ └── image-dialog.js │ │ ├── link-dialog │ │ └── link-dialog.js │ │ ├── plugin-template.js │ │ ├── preformatted-text-dialog │ │ └── preformatted-text-dialog.js │ │ ├── reference-link-dialog │ │ └── reference-link-dialog.js │ │ ├── table-dialog │ │ └── table-dialog.js │ │ └── test-plugin │ │ └── test-plugin.js └── fileapi │ ├── FileAPI.html5.js │ ├── FileAPI.html5.min.js │ ├── FileAPI.js │ └── FileAPI.min.js ├── scripts └── tinymce.plugins │ └── imageupload │ ├── dialog.html │ └── plugin.js └── themes └── default └── styles ├── account.css └── main.css /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 3 | ################################################################################ 4 | 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | [Xx]64/ 21 | [Xx]86/ 22 | [Bb]uild/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | /.vs 28 | /src/DotNetBlog.Admin/node_modules 29 | /src/DotNetBlog.Admin/**/*.js.map 30 | /src/DotNetBlog.Web/wwwroot/app/**/*.js.map 31 | /src/DotNetBlog.Web/wwwroot/dist 32 | /src/DotNetBlog.Web/wwwroot/upload 33 | /src/DotNetBlog.Web/wwwroot/app/dist 34 | !/src/DotNetBlog.Web/wwwroot/app/webpack.config.js 35 | /src/DotNetBlog.Web/App_Data/ 36 | .vs/ -------------------------------------------------------------------------------- /Nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DotNetBlog 2 | A Tiny Blog Written in Asp.Net Core 3 | 4 | The blog is hosted on [http://120.24.36.219/](http://120.24.36.219/) 5 | 6 | How to Build and Run: 7 | 8 | * Clone the repository 9 | * Restore the dependencies 10 | 11 | ``` 12 | dotnet restore 13 | ``` 14 | * Build admin portal 15 | 16 | ``` 17 | cd src/DotNetBlog.Admin 18 | npm install 19 | webpack 20 | ``` 21 | * Install front-end client libraries 22 | 23 | ``` 24 | cd src/DotNetBlog.Web 25 | bower install 26 | ``` 27 | * Edit connection string 28 | 29 | Open 'src/DotNetBlog.Web/App_Data/config.json' to specify you own connection string. 30 | 31 | ``` 32 | { 33 | "database": "sqlite", 34 | "connectionString": "DataSource=App_Data/blog.db" 35 | //"database": "sqlserver", 36 | //"connectionString": "server=.\\SqlServer2008;database=DotNetBlog;uid=sa;pwd=123456;" 37 | } 38 | ``` 39 | 40 | DotNetBlog supports two kinds of database. You can set "database" to "sqite" or "sqlserver" 41 | * Run the project 42 | 43 | ``` 44 | dotnet run 45 | ``` 46 | * Initialize the blog 47 | 48 | You can access 'http://{YourBlogAddress}/install' to initialize the blog, this will help to create a default admin user, which username and password are both 'admin'. 49 | 50 | The project is still in DEVELOPMENT! -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src", "test" ], 3 | "sdk": { "version": "2.0.0" } 4 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react", "es2015", "stage-0"] 3 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/actions/index.js: -------------------------------------------------------------------------------- 1 | var Consts = require("../consts") 2 | 3 | function changeMenu(menu, subMenu) { 4 | var action = { 5 | type: Consts.ActionTypes.ChangeMenu, 6 | menu: menu, 7 | subMenu: subMenu 8 | }; 9 | return action; 10 | } 11 | 12 | function changeTopicSetting(setting){ 13 | var action = { 14 | type: Consts.ActionTypes.ChangeTopicSetting, 15 | setting: setting 16 | }; 17 | return action; 18 | } 19 | 20 | function changePageSetting(setting){ 21 | var action = { 22 | type: Consts.ActionTypes.changePageSetting, 23 | setting: setting 24 | } 25 | } 26 | 27 | module.exports = { 28 | changeMenu, 29 | changeTopicSetting, 30 | changePageSetting 31 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/components/bootstrap/formgroup.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | 3 | class FormGroup extends React.Component{ 4 | render(){ 5 | let className = "form-group"; 6 | if(this.props.validation && this.props.validation.touched && this.props.validation.error){ 7 | className += " has-error" 8 | } 9 | 10 | return ( 11 |
12 | {this.renderLabel()} 13 | {this.props.children} 14 | {this.renderError()} 15 |
16 | ) 17 | } 18 | 19 | renderLabel(){ 20 | if(this.props.label){ 21 | return ( 22 | 23 | ) 24 | } 25 | else{ 26 | return null; 27 | } 28 | } 29 | 30 | renderError(){ 31 | if(this.props.validation && this.props.validation.touched && this.props.validation.error){ 32 | return {this.props.validation.error} 33 | } 34 | return null; 35 | } 36 | } 37 | 38 | module.exports = FormGroup; -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/components/form.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | var Formsy = require("formsy-react") 3 | var FRC = require("formsy-react-components") 4 | 5 | const Form = React.createClass({ 6 | mixins: [FRC.ParentContextMixin], 7 | render() { 8 | return ( 9 | 14 | {this.props.children} 15 | 16 | ); 17 | }, 18 | reset(model){ 19 | this.refs.formsy.reset(model) 20 | }, 21 | submit(){ 22 | this.refs.formsy.submit() 23 | }, 24 | getModel(){ 25 | return this.refs.formsy.getModel() 26 | } 27 | }) 28 | 29 | Form.propTypes = Formsy.Form.propTypes 30 | 31 | module.exports = Form; -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/components/index.jsx: -------------------------------------------------------------------------------- 1 | const Form = require("./form") 2 | const LoadingButton = require("./loadingbutton") 3 | const ContentHeader = require("./contentheader") 4 | const Editor = require("./editor") 5 | const Pager = require("./pager") 6 | const Spinner = require("./spinner") 7 | const FormGroup = require("./bootstrap/formgroup") 8 | 9 | module.exports = { 10 | Form, 11 | LoadingButton, 12 | ContentHeader, 13 | Editor, 14 | Pager, 15 | Spinner, 16 | Bootstrap: { 17 | FormGroup 18 | } 19 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/components/loadingbutton.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react"); 2 | 3 | class LoadingButton extends React.Component{ 4 | render(){ 5 | let disabled = this.props.loading 6 | 7 | return ( 8 | 13 | ); 14 | } 15 | renderSpinner(){ 16 | if(this.props.loading){ 17 | return ; 18 | } 19 | else{ 20 | return null; 21 | } 22 | } 23 | } 24 | 25 | LoadingButton.propTypes = { 26 | children: React.PropTypes.node, 27 | loading: React.PropTypes.bool.isRequired 28 | }; 29 | 30 | module.exports = LoadingButton -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/components/spinner.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | 3 | class Spinner extends React.Component{ 4 | render(){ 5 | if(this.props.loading){ 6 | return ( 7 |
8 |
9 |
10 | ) 11 | } 12 | else{ 13 | return null; 14 | } 15 | } 16 | } 17 | 18 | Spinner.propTypes = { 19 | loading: React.PropTypes.bool.isRequired 20 | } 21 | 22 | module.exports = Spinner -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/img/boxed-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Admin/img/boxed-bg.jpg -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/img/boxed-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Admin/img/boxed-bg.png -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/img/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Admin/img/icons.png -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6" 4 | }, 5 | "exclude": [ 6 | "node_modules" 7 | ] 8 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "async": "^2.0.0-rc.6", 14 | "babel-core": "^6.10.4", 15 | "babel-loader": "^6.2.4", 16 | "babel-plugin-add-module-exports": "^0.2.1", 17 | "babel-plugin-dev-expression": "^0.2.1", 18 | "babel-plugin-transform-es2015-modules-umd": "^6.12.0", 19 | "babel-plugin-transform-object-assign": "^6.8.0", 20 | "babel-plugin-transform-react-remove-prop-types": "^0.4.8", 21 | "babel-preset-es2015": "^6.9.0", 22 | "babel-preset-react": "^6.11.1", 23 | "babel-preset-stage-0": "^6.5.0", 24 | "bootstrap": "^3.3.6", 25 | "bootstrap-tagsinput": "^0.7.1", 26 | "css-loader": "^0.23.1", 27 | "formsy-react": "^0.18.0", 28 | "formsy-react-components": "^0.8.0", 29 | "history": "^3.0.0", 30 | "jsx-loader": "^0.13.2", 31 | "react": "^15.1.0", 32 | "react-bootstrap": "^0.29.5", 33 | "react-bootstrap-table": "^2.3.8", 34 | "react-dom": "^15.1.0", 35 | "react-hot-loader": "^1.3.0", 36 | "react-redux": "^4.4.5", 37 | "react-router": "^2.5.1", 38 | "react-tagsinput": "^3.9.1", 39 | "react-tinymce": "^0.5.1", 40 | "redux": "^3.5.2", 41 | "redux-form": "^5.3.2", 42 | "redux-thunk": "^2.1.0", 43 | "style-loader": "^0.13.1", 44 | "webpack": "^1.13.1", 45 | "webpack-dev-server": "^1.14.1", 46 | "whatwg-fetch": "^1.0.0" 47 | }, 48 | "dependencies": { 49 | "react-localization": "0.0.13", 50 | "react-sortable": "^1.0.3" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/reducers/index.js: -------------------------------------------------------------------------------- 1 | var Consts = require("../consts") 2 | 3 | const {ActionTypes} = Consts 4 | 5 | function Reducer(state = {}, action) { 6 | switch (action.type) { 7 | case ActionTypes.ChangeMenu: 8 | return _.assign({}, state, { menu: action.menu, subMenu: action.subMenu }); 9 | case ActionTypes.ChangeTopicSetting: 10 | localStorage.setItem(Consts.LocalStorage.TopicSetting, JSON.stringify(action.setting)); 11 | return _.assign({}, state, {topicSetting: action.setting}); 12 | default: 13 | return state; 14 | } 15 | } 16 | 17 | module.exports = Reducer; -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/server.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var WebpackDevServer = require('webpack-dev-server'); 3 | var config = require('./webpack.config'); 4 | 5 | new WebpackDevServer(webpack(config), { 6 | publicPath: config.output.publicPath, 7 | hot: true, 8 | historyApiFallback: true 9 | }).listen(8080, 'localhost', function (err, result) { 10 | if (err) { 11 | return console.log(err); 12 | } 13 | 14 | console.log('Listening at http://localhost:8080/'); 15 | }); -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/services/dialog.js: -------------------------------------------------------------------------------- 1 | toastr.options.timeOut = 5000; 2 | toastr.options.extendedTimeOut = 2000; 3 | 4 | function createOption(callback){ 5 | return { 6 | onHidden: callback 7 | } 8 | } 9 | 10 | const Dialog = { 11 | success(message, title, callback){ 12 | toastr.success(message, title, createOption(callback)); 13 | }, 14 | error(message, title, callback){ 15 | toastr.error(message, title, createOption(callback)); 16 | }, 17 | info(message, title, callback){ 18 | toastr.info(message, title, createOption(callback)) 19 | } 20 | } 21 | 22 | module.exports = Dialog -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/services/index.js: -------------------------------------------------------------------------------- 1 | const Api = require("./api") 2 | const Dialog = require("./dialog") 3 | 4 | module.exports = { 5 | Api, 6 | Dialog 7 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/store/index.js: -------------------------------------------------------------------------------- 1 | var {createStore, applyMiddleware, combineReducers} = require("redux") 2 | var Reducer = require("../reducers") 3 | var Thunk = require("redux-thunk").default 4 | var ReduxForm = require("redux-form") 5 | var Consts = require("../consts") 6 | 7 | const reducers = combineReducers({ 8 | blog: Reducer, 9 | form: ReduxForm.reducer 10 | }) 11 | 12 | function getInitialState(){ 13 | var state = { 14 | blog: { 15 | 16 | } 17 | }; 18 | 19 | var topicSetting = localStorage.getItem(Consts.LocalStorage.TopicSetting); 20 | try{ 21 | topicSetting = JSON.parse(topicSetting); 22 | } 23 | catch(e){ 24 | topicSetting = {}; 25 | } 26 | state.blog.topicSetting = topicSetting || {}; 27 | 28 | var pageSetting = localStorage.getItem(Consts.LocalStorage.PageSetting); 29 | try{ 30 | pageSetting = JSON.parse(pageSetting); 31 | } 32 | catch(e){ 33 | pageSetting = {}; 34 | } 35 | state.blog.pageSetting = pageSetting || {}; 36 | 37 | console.log(state); 38 | 39 | return state; 40 | } 41 | 42 | const initialState = getInitialState(); 43 | 44 | const store = createStore(reducers, initialState, applyMiddleware(Thunk)) 45 | 46 | module.exports = store -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/async/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/2901b0c3c4e17d7b09d6b97abe12616b68ba0643/async/async.d.ts", 5 | "raw": "registry:dt/async#1.4.2+20160602152629", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/2901b0c3c4e17d7b09d6b97abe12616b68ba0643/async/async.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/lodash/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/49164be32a8d6089a7fff0e29057e23a811da4c9/lodash/lodash-3.10.d.ts", 5 | "raw": "registry:dt/lodash#3.10.0+20160619033623", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/49164be32a8d6089a7fff0e29057e23a811da4c9/lodash/lodash-3.10.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/react-bootstrap/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/34ed89d9a82f7266f8287d2120b63e9bbed558cb/react-bootstrap/react-bootstrap.d.ts", 5 | "raw": "registry:dt/react-bootstrap#0.0.0+20160627163812", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/34ed89d9a82f7266f8287d2120b63e9bbed558cb/react-bootstrap/react-bootstrap.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/react-redux/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/0b96933934c2e37a749aad8e38e23214e21e7dab/react-redux/react-redux.d.ts", 5 | "raw": "registry:dt/react-redux#4.4.0+20160501125835", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/0b96933934c2e37a749aad8e38e23214e21e7dab/react-redux/react-redux.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/react-router/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/d5282ee8f189fa4dc5f8ffa05cec7937432b1c5d/react-router/react-router.d.ts", 5 | "raw": "registry:dt/react-router#2.0.0+20160621215300", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/d5282ee8f189fa4dc5f8ffa05cec7937432b1c5d/react-router/react-router.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/react/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/59260ed0583a68551f4f651791a2848c82cf5a13/react/react.d.ts", 5 | "raw": "registry:dt/react#0.14.0+20160621225615", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/59260ed0583a68551f4f651791a2848c82cf5a13/react/react.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/redux-thunk/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/redux-thunk/redux-thunk.d.ts 3 | declare namespace ReduxThunk { 4 | export interface Thunk extends Redux.Middleware {} 5 | export interface ThunkInterface { 6 | (dispatch: Redux.Dispatch, getState?: () => T): any; 7 | } 8 | } 9 | 10 | declare module "redux-thunk" { 11 | var thunk: ReduxThunk.Thunk; 12 | export default thunk; 13 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/redux-thunk/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/redux-thunk/redux-thunk.d.ts", 5 | "raw": "registry:dt/redux-thunk#2.0.1+20160317120654", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/redux-thunk/redux-thunk.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/redux/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c2bfaedeee7ae4ed5e0f01ebcf4af7acfe2c77c3/redux/redux.d.ts 3 | declare namespace Redux { 4 | 5 | interface ActionCreator extends Function { 6 | (...args: any[]): any; 7 | } 8 | 9 | interface Reducer extends Function { 10 | (state: any, action: any): any; 11 | } 12 | 13 | interface Dispatch extends Function { 14 | (action: any): any; 15 | } 16 | 17 | interface StoreMethods { 18 | dispatch: Dispatch; 19 | getState(): any; 20 | } 21 | 22 | 23 | interface MiddlewareArg { 24 | dispatch: Dispatch; 25 | getState: Function; 26 | } 27 | 28 | interface Middleware extends Function { 29 | (obj: MiddlewareArg): Function; 30 | } 31 | 32 | class Store { 33 | getReducer(): Reducer; 34 | replaceReducer(nextReducer: Reducer): void; 35 | dispatch(action: any): any; 36 | getState(): any; 37 | subscribe(listener: Function): Function; 38 | } 39 | 40 | function createStore(reducer: Reducer, initialState?: any, enhancer?: Function): Store; 41 | function bindActionCreators(actionCreators: T, dispatch: Dispatch): T; 42 | function combineReducers(reducers: any): Reducer; 43 | function applyMiddleware(...middlewares: Middleware[]): Function; 44 | function compose(...functions: Function[]): T; 45 | } 46 | 47 | declare module "redux" { 48 | export = Redux; 49 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/redux/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c2bfaedeee7ae4ed5e0f01ebcf4af7acfe2c77c3/redux/redux.d.ts", 5 | "raw": "registry:dt/redux#3.3.1+20160326112656", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c2bfaedeee7ae4ed5e0f01ebcf4af7acfe2c77c3/redux/redux.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/globals/toastr/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/384a53f595cdba08d1398902e53c6901700ec459/toastr/toastr.d.ts", 5 | "raw": "registry:dt/toastr#2.1.1+20160510010435", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/384a53f595cdba08d1398902e53c6901700ec459/toastr/toastr.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/views/dashboard/dashboard.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | var Statistics = require("./statistics") 3 | var RecentComment = require("./recentcomment") 4 | var QuickPost = require("./quickpost") 5 | var TopicDraft = require("./topicdraft") 6 | 7 | class Dashboard extends React.Component{ 8 | onSaveDraft(){ 9 | this.refs.topicDraft.loadData() 10 | } 11 | 12 | render() { 13 | return ( 14 |
15 |
16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 |
25 | 26 |
27 |
28 | ) 29 | } 30 | } 31 | 32 | module.exports = Dashboard -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/views/widget/widgetinfo.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | var {Modal, ModalHeader, ModalTitle, ModalBody, ModalFooter} = require("react-bootstrap") 3 | 4 | class WidgetInfo extends React.Component{ 5 | constructor(){ 6 | super() 7 | 8 | this.state = { 9 | show: false, 10 | widget: { 11 | 12 | } 13 | } 14 | } 15 | 16 | show(widget){ 17 | this.setState({ 18 | show: true, 19 | widget: widget 20 | }) 21 | } 22 | 23 | close(){ 24 | this.setState({ 25 | show: false 26 | }) 27 | } 28 | 29 | render(){ 30 | let icon = "/images/widget/" + this.state.widget.icon + ".png"; 31 | return ( 32 | 33 | {this.state.widget.name} 34 | 35 |

36 | 37 |

38 |
39 | 40 | 41 | 42 |
43 | ) 44 | } 45 | } 46 | 47 | module.exports = WidgetInfo -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/views/widget/widgetitem.jsx: -------------------------------------------------------------------------------- 1 | var React = require("react") 2 | var {sortable} = require("react-sortable") 3 | 4 | var WidgetItem = React.createClass({ 5 | displayName: 'WidgetItem', 6 | render: function() { 7 | return ( 8 |
  • 9 | {this.props.children.widget.config.title} 10 | 11 | 12 | 13 | 14 |
  • 15 | ) 16 | } 17 | }) 18 | 19 | module.exports = sortable(WidgetItem) -------------------------------------------------------------------------------- /src/DotNetBlog.Admin/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); 4 | 5 | var args = process.argv; 6 | var release = args.indexOf("--release") > -1; 7 | 8 | var entry = [] 9 | var plugins = [] 10 | if(release){ 11 | entry = [ 12 | './index.jsx' 13 | ]; 14 | plugins = [ 15 | new webpack.optimize.OccurenceOrderPlugin(), 16 | new webpack.DefinePlugin({ 17 | 'process.env': { NODE_ENV: '"production"' } 18 | }), 19 | new webpack.optimize.UglifyJsPlugin({minimize: true}) 20 | ]; 21 | } 22 | else{ 23 | entry = [ 24 | "webpack-dev-server/client?http://localhost:8080", 25 | "webpack/hot/only-dev-server", 26 | './index.jsx' 27 | ]; 28 | plugins = [ 29 | new webpack.HotModuleReplacementPlugin() 30 | ] 31 | } 32 | 33 | module.exports = { 34 | entry: entry, 35 | output: { 36 | path: path.normalize(path.join(__dirname, '../DotNetBlog.Web/wwwroot/dist')), 37 | filename: 'app.js', 38 | publicPath: "http://localhost:8080/" 39 | }, 40 | resolve: { 41 | extensions: ['', '.js', '.jsx', '.css', '.scss'] 42 | }, 43 | plugins: plugins, 44 | module: { 45 | loaders: [{ 46 | test: /\.css$/, 47 | loaders: ['style', 'css'] 48 | }, { 49 | test: /\.jsx$/, 50 | loaders: ["react-hot-loader", "babel-loader"] 51 | }, { 52 | test: /\.js$/, 53 | loaders: ["babel-loader"] 54 | },{ 55 | test: /\.(jpg|gif)$/, 56 | loader: "url-loader" 57 | }] 58 | } 59 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/CategoryMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class CategoryMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Category"); 16 | builder.HasKey(t => t.ID); 17 | 18 | builder.Property(t => t.ID).ValueGeneratedOnAdd().UseSqlServerIdentityColumn(); 19 | builder.Property(t => t.Name).IsRequired().HasMaxLength(50); 20 | builder.Property(t => t.Description).HasMaxLength(200); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/CategoryTopicMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class CategoryTopicMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("CategoryTopic"); 16 | 17 | builder.HasKey(t => new { t.CategoryID, t.TopicID }); 18 | builder.HasOne(t => t.Category).WithMany(); 19 | builder.HasOne(t => t.Topic).WithMany(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/CommentMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class CommentMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Comment"); 16 | 17 | builder.HasKey(t => t.ID); 18 | 19 | builder.Property(t => t.ID).ValueGeneratedOnAdd().UseSqlServerIdentityColumn(); 20 | 21 | builder.Property(t => t.Content).IsRequired(); 22 | builder.Property(t => t.CreateIP).IsRequired().HasMaxLength(40); 23 | builder.Property(t => t.Email).IsRequired().HasMaxLength(100); 24 | builder.Property(t => t.Name).IsRequired().HasMaxLength(20); 25 | builder.Property(t => t.WebSite).HasMaxLength(100); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/LinkMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Core.Data.Mappings 9 | { 10 | public sealed class LinkMapping 11 | { 12 | //public static void Map(EntityTypeBuilder builder) 13 | //{ 14 | 15 | //} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/PageMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public sealed class PageMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Page"); 16 | 17 | builder.HasKey(t => t.ID); 18 | 19 | builder.HasIndex(t => t.Alias).IsUnique(); 20 | 21 | builder.Property(t => t.ID).ValueGeneratedOnAdd().UseSqlServerIdentityColumn(); 22 | builder.Property(t => t.Title).IsRequired().HasMaxLength(100); 23 | builder.Property(t => t.Alias).HasMaxLength(100); 24 | builder.Property(t => t.Keywords).HasMaxLength(100); 25 | builder.Property(t => t.Description).HasMaxLength(500); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/SettingMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class SettingMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Setting"); 16 | 17 | builder.HasKey(t => t.Key); 18 | 19 | builder.Property(t => t.Key).HasMaxLength(50); 20 | builder.Property(t => t.Value).IsRequired(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/TagMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class TagMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Tag"); 16 | 17 | builder.HasIndex(t => t.Keyword).IsUnique(); 18 | 19 | builder.HasKey(t => t.ID); 20 | builder.Property(t => t.ID).ValueGeneratedOnAdd().UseSqlServerIdentityColumn(); 21 | builder.Property(t => t.Keyword).IsRequired().HasMaxLength(100); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/TagTopicMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class TagTopicMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("TagTopic"); 16 | 17 | builder.HasKey(t => new { t.TagID, t.TopicID }); 18 | builder.HasOne(t => t.Topic).WithMany(); 19 | builder.HasOne(t => t.Tag).WithMany(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/TopicMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public static class TopicMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Topic"); 16 | 17 | builder.HasKey(t => t.ID); 18 | 19 | builder.HasIndex(t => t.Alias).IsUnique(); 20 | 21 | builder.Property(t => t.ID).ValueGeneratedOnAdd().UseSqlServerIdentityColumn(); 22 | builder.Property(t => t.Title).IsRequired().HasMaxLength(100); 23 | builder.Property(t => t.Alias).HasMaxLength(100); 24 | builder.Property(t => t.Summary).HasMaxLength(200); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/UserMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public sealed class UserMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("User"); 16 | 17 | builder.HasIndex(t => t.UserName).IsUnique(); 18 | 19 | builder.HasKey(t => t.ID); 20 | 21 | builder.Property(t => t.UserName).IsRequired().HasMaxLength(20); 22 | builder.Property(t => t.Password).IsRequired().HasMaxLength(32); 23 | builder.Property(t => t.Nickname).IsRequired().HasMaxLength(20); 24 | builder.Property(t => t.Email).HasMaxLength(100); 25 | builder.Property(t => t.Avatar).HasMaxLength(100); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/UserTokenMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public sealed class UserTokenMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("UserToken"); 16 | 17 | builder.HasKey(t => t.Token); 18 | 19 | builder.Property(t => t.Token).HasMaxLength(32); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Data/Mappings/WidgetMapping.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Entity; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | 9 | namespace DotNetBlog.Core.Data.Mappings 10 | { 11 | public sealed class WidgetMapping 12 | { 13 | public static void Map(EntityTypeBuilder builder) 14 | { 15 | builder.ToTable("Widget"); 16 | 17 | builder.HasKey(t => new { t.ID }); 18 | 19 | builder.Property(t => t.Config).IsRequired(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Category.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Category 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public string Description { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/CategoryTopic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class CategoryTopic 9 | { 10 | public int CategoryID { get; set; } 11 | 12 | public int TopicID { get; set; } 13 | 14 | public virtual Category Category { get; set; } 15 | 16 | public virtual Topic Topic { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Comment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Comment 9 | { 10 | public int ID { get; set; } 11 | 12 | public int TopicID { get; set; } 13 | 14 | public int? ReplyToID { get; set; } 15 | 16 | public Enums.CommentStatus Status { get; set; } 17 | 18 | public string Email { get; set; } 19 | 20 | public string Name { get; set; } 21 | 22 | public string WebSite { get; set; } 23 | 24 | public string Content { get; set; } 25 | 26 | public DateTime CreateDate { get; set; } 27 | 28 | public string CreateIP { get; set; } 29 | 30 | public bool NotifyOnComment { get; set; } 31 | 32 | public int? UserID { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Link.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Link 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Title { get; set; } 13 | 14 | public string Url { get; set; } 15 | 16 | public int Sort { get; set; } 17 | 18 | public string OpenInNewWindow { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Page.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Entity 8 | { 9 | public class Page 10 | { 11 | public int ID { get; set; } 12 | 13 | public int? ParentID { get; set; } 14 | 15 | public string Title { get; set; } 16 | 17 | public string Content { get; set; } 18 | 19 | public string Alias { get; set; } 20 | 21 | public string Keywords { get; set; } 22 | 23 | public string Description { get; set; } 24 | 25 | public DateTime CreateDate { get; set; } 26 | 27 | public DateTime EditDate { get; set; } 28 | 29 | public bool IsHomePage { get; set; } 30 | 31 | public bool ShowInList { get; set; } 32 | 33 | public int Order { get; set; } 34 | 35 | public PageStatus Status { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Setting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Setting 9 | { 10 | public string Key { get; set; } 11 | 12 | public string Value { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Tag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Tag 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Keyword { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/TagTopic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class TagTopic 9 | { 10 | public int TagID { get; set; } 11 | 12 | public int TopicID { get; set; } 13 | 14 | public virtual Tag Tag { get; set; } 15 | 16 | public virtual Topic Topic { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Topic.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Entity 8 | { 9 | public class Topic 10 | { 11 | public int ID { get; set; } 12 | 13 | public string Title { get; set; } 14 | 15 | public string Content { get; set; } 16 | 17 | public string Alias { get; set; } 18 | 19 | public string Summary { get; set; } 20 | 21 | public bool AllowComment { get; set; } 22 | 23 | public TopicStatus Status { get; set; } 24 | 25 | public int CreateUserID { get; set; } 26 | 27 | public DateTime CreateDate { get; set; } 28 | 29 | public int EditUserID { get; set; } 30 | 31 | public DateTime EditDate { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class User 9 | { 10 | public int ID { get; set; } 11 | 12 | public string UserName { get; set; } 13 | 14 | public string Password { get; set; } 15 | 16 | public string Email { get; set; } 17 | 18 | public string Nickname { get; set; } 19 | 20 | public DateTime? LoginDate { get; set; } 21 | 22 | public string Avatar { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | 12 | public int UserID { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Entity/Widget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Entity 7 | { 8 | public class Widget 9 | { 10 | public int ID { get; set; } 11 | 12 | public Enums.WidgetType Type { get; set; } 13 | 14 | public string Config { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Enums/CommentStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Enums 7 | { 8 | public enum CommentStatus : byte 9 | { 10 | Pending = 0, 11 | 12 | Approved = 1, 13 | 14 | Reject = 2, 15 | 16 | Junk = 255 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Enums/PageStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Enums 7 | { 8 | public enum PageStatus 9 | { 10 | Draft = 0, 11 | Published = 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Enums/TopicStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Enums 7 | { 8 | public enum TopicStatus : byte 9 | { 10 | Draft = 0, 11 | Published = 1, 12 | Trash = 255 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Enums/WidgetType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Enums 7 | { 8 | public enum WidgetType : byte 9 | { 10 | Administration = 1, 11 | 12 | Category = 2, 13 | 14 | Tag = 3, 15 | 16 | RecentTopic = 4, 17 | 18 | RecentComment = 5, 19 | 20 | MonthStatistics = 6, 21 | 22 | Page = 7, 23 | 24 | Search = 8, 25 | 26 | Link = 9 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Extensions/MemoryCacheExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Caching.Memory; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Extensions 8 | { 9 | public static class MemoryCacheExtensions 10 | { 11 | public static T RetriveCache(this IMemoryCache cache, string cacheKey, Func func, MemoryCacheEntryOptions options = null) 12 | { 13 | var result = cache.Get(cacheKey); 14 | 15 | if (result == null) 16 | { 17 | result = func(); 18 | 19 | if (options == null) 20 | { 21 | cache.Set(cacheKey, result); 22 | } 23 | else 24 | { 25 | cache.Set(cacheKey, result, options); 26 | } 27 | } 28 | 29 | return result; 30 | } 31 | 32 | public static async Task RetriveCacheAsync(this IMemoryCache cache, string cacheKey, Func> func, MemoryCacheEntryOptions options = null) 33 | { 34 | var result = cache.Get(cacheKey); 35 | 36 | if (result == null) 37 | { 38 | result = await func(); 39 | 40 | if (options == null) 41 | { 42 | cache.Set(cacheKey, result); 43 | } 44 | else 45 | { 46 | cache.Set(cacheKey, result, options); 47 | } 48 | } 49 | 50 | return result; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/IServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Page; 2 | using DotNetBlog.Core.Model.Setting; 3 | using DotNetBlog.Core.Service; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | using System.Reflection; 10 | using DotNetBlog.Core.Model.Theme; 11 | using Microsoft.AspNetCore.Http; 12 | 13 | namespace DotNetBlog.Core 14 | { 15 | public static class IServiceCollectionExtensions 16 | { 17 | public static void AddBlogService(this IServiceCollection services) 18 | { 19 | var assembly = typeof(IServiceCollectionExtensions).GetTypeInfo().Assembly; 20 | var serviceList = assembly.DefinedTypes.Where(t => t.Name.EndsWith("Service") && t.Namespace == "DotNetBlog.Core.Service").ToList(); 21 | foreach (var service in serviceList) 22 | { 23 | services.AddScoped(service.AsType()); 24 | } 25 | 26 | services.AddScoped(provider => 27 | { 28 | return provider.GetService().Get(); 29 | }); 30 | 31 | services.AddScoped(provider => 32 | { 33 | return provider.GetService().Get(); 34 | }); 35 | 36 | services.AddScoped(); 37 | 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Category/CategoryBasicModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Category 7 | { 8 | public class CategoryBasicModel 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Name { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Category/CategoryModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Topic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Category 8 | { 9 | public class CategoryModel : CategoryBasicModel 10 | { 11 | public string Description { get; set; } 12 | 13 | public TopicCountModel Topics { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Comment/AddCommentModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Comment 8 | { 9 | public class AddCommentModel 10 | { 11 | [Required] 12 | public int? TopicID { get; set; } 13 | 14 | public int? ReplyTo { get; set; } 15 | 16 | [Required] 17 | [EmailAddress] 18 | public string Email { get; set; } 19 | 20 | [Required] 21 | public string Name { get; set; } 22 | 23 | public string WebSite { get; set; } 24 | 25 | [Required] 26 | public string Content { get; set; } 27 | 28 | public bool NotifyOnComment { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Comment/CommentCountModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Comment 7 | { 8 | public class CommentCountModel 9 | { 10 | public int Pending { get; set; } 11 | 12 | public int Approved { get; set; } 13 | 14 | public int Reject { get; set; } 15 | 16 | public int Total { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Comment/CommentItemModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Comment 7 | { 8 | public class CommentItemModel 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public string Content { get; set; } 15 | 16 | public Topic.TopicBasicModel Topic { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Comment/CommentModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Comment 7 | { 8 | public class CommentModel 9 | { 10 | public int ID { get; set; } 11 | 12 | public int TopicID { get; set; } 13 | 14 | public int? ReplyToID { get; set; } 15 | 16 | public string Name { get; set; } 17 | 18 | public string Email { get; set; } 19 | 20 | public string WebSite { get; set; } 21 | 22 | public string Content { get; set; } 23 | 24 | public Enums.CommentStatus Status { get; set; } 25 | 26 | public DateTime CreateDate { get; set; } 27 | 28 | public string CreateIP { get; set; } 29 | 30 | public UserModel User { get; set; } 31 | 32 | public class UserModel 33 | { 34 | public int ID { get; set; } 35 | 36 | public string UserName { get; set; } 37 | 38 | public string Email { get; set; } 39 | 40 | public string Nickname { get; set; } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Email/CommentEmailModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Topic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Email 8 | { 9 | public class CommentEmailModel 10 | { 11 | public TopicModel Topic { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Email/TestEmailConfigModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Email 7 | { 8 | public class TestEmailConfigModel 9 | { 10 | public string EmailAddress { get; set; } 11 | 12 | public string User { get; set; } 13 | 14 | public string Password { get; set; } 15 | 16 | public int Port { get; set; } 17 | 18 | public string Server { get; set; } 19 | 20 | public bool EnableSSL { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Install/InstallModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Text; 5 | 6 | namespace DotNetBlog.Core.Model.Install 7 | { 8 | public class InstallModel 9 | { 10 | [Required] 11 | [StringLength(20)] 12 | public string UserName { get; set; } 13 | 14 | [Required] 15 | [StringLength(20)] 16 | public string Password { get; set; } 17 | 18 | [Required] 19 | [EmailAddress] 20 | [StringLength(100)] 21 | public string Email { get; set; } 22 | 23 | [Required] 24 | [Compare(nameof(Password))] 25 | public string ConfirmPassword { get; set; } 26 | 27 | [Required] 28 | [StringLength(20)] 29 | public string Nickname { get; set; } 30 | 31 | [Required] 32 | [StringLength(100)] 33 | public string BlogTitle { get; set; } 34 | 35 | [Required] 36 | [StringLength(100)] 37 | public string BlogHost { get; set; } 38 | 39 | [Required] 40 | public string Language { get; set; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Page/AddPageModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Page 8 | { 9 | public class AddPageModel 10 | { 11 | [Required] 12 | [StringLength(100)] 13 | public string Title { get; set; } 14 | 15 | [Required] 16 | public string Content { get; set; } 17 | 18 | [StringLength(100)] 19 | public string Alias { get; set; } 20 | 21 | [StringLength(100)] 22 | public string Keywords { get; set; } 23 | 24 | [StringLength(500)] 25 | public string Description { get; set; } 26 | 27 | public DateTime? Date { get; set; } 28 | 29 | public int? Parent { get; set; } 30 | 31 | public int Order { get; set; } 32 | 33 | public bool IsHomePage { get; set; } 34 | 35 | public bool ShowInList { get; set; } 36 | 37 | public Enums.PageStatus Status { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Page/EditPageModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Page 7 | { 8 | public class EditPageModel : AddPageModel 9 | { 10 | public int ID { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Page/PageBasicModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Page 7 | { 8 | public class PageBasicModel 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Title { get; set; } 13 | 14 | public string Alias { get; set; } 15 | 16 | public PageBasicModel Parent { get; set; } 17 | 18 | public int Order { get; set; } 19 | 20 | public DateTime Date { get; set; } 21 | 22 | public bool IsHomePage { get; set; } 23 | 24 | public bool ShowInList { get; set; } 25 | 26 | public Enums.PageStatus Status { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Page/PageCountModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Page 7 | { 8 | public class PageCountModel 9 | { 10 | public int Published { get; set; } 11 | 12 | public int Draft { get; set; } 13 | 14 | public int All { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Page/PageModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Page 7 | { 8 | public class PageModel : PageBasicModel 9 | { 10 | public string Content { get; set; } 11 | 12 | public string Keywords { get; set; } 13 | 14 | public string Summary { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Statistics/BlogStatisticsModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Statistics 7 | { 8 | public class BlogStatisticsModel 9 | { 10 | public Topic.TopicCountModel Topics { get; set; } 11 | 12 | public Comment.CommentCountModel Comments { get; set; } 13 | 14 | public Page.PageCountModel Pages { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Tag/TagModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Topic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Tag 8 | { 9 | public class TagModel 10 | { 11 | public int ID { get; set; } 12 | 13 | public string Keyword { get; set; } 14 | 15 | public TopicCountModel Topics { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Theme/ThemeModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DotNetBlog.Core.Model.Theme 7 | { 8 | public class ThemeModel 9 | { 10 | [JsonIgnore] 11 | public string Path { get; set; } 12 | 13 | public string Key { get; set; } 14 | 15 | public string Name { get; set; } 16 | public string Description { get; set; } 17 | public string ThemeUrl { get; set; } 18 | public string Author { get; set; } 19 | public string AuthorUrl { get; set; } 20 | public string AuthorEmail { get; set; } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/AddTopicModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Core.Model.Topic 9 | { 10 | public class AddTopicModel 11 | { 12 | [Required] 13 | [StringLength(100)] 14 | public string Title { get; set; } 15 | 16 | [Required] 17 | public string Content { get; set; } 18 | 19 | [StringLength(100)] 20 | public string Alias { get; set; } 21 | 22 | [StringLength(200)] 23 | public string Summary { get; set; } 24 | 25 | public int[] CategoryList { get; set; } 26 | 27 | public string[] TagList { get; set; } 28 | 29 | public bool AllowComment { get; set; } 30 | 31 | public DateTime? Date { get; set; } 32 | 33 | public TopicStatus Status { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/EditTopicModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Topic 7 | { 8 | public class EditTopicModel : AddTopicModel 9 | { 10 | public int ID { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/ITopicModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Topic 7 | { 8 | public interface ITopicModel 9 | { 10 | int ID { get; } 11 | 12 | string Title { get; } 13 | 14 | string Alias { get; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/MonthStatisticsModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Topic 7 | { 8 | public class MonthStatisticsModel 9 | { 10 | public DateTime Month { get; set; } 11 | 12 | public TopicCountModel Topics { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/TopicBasicModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Topic 7 | { 8 | public class TopicBasicModel : ITopicModel 9 | { 10 | public int ID { get; set; } 11 | 12 | public string Title { get; set; } 13 | 14 | public string Alias { get; set; } 15 | 16 | public Comment.CommentCountModel Comments { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/TopicCountModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Topic 7 | { 8 | public class TopicCountModel 9 | { 10 | public int Published { get; set; } 11 | 12 | public int Draft { get; set; } 13 | 14 | public int All { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Topic/TopicModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Category; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Topic 8 | { 9 | public class TopicModel : TopicBasicModel, ITopicModel 10 | { 11 | public string Summary { get; set; } 12 | 13 | public string Content { get; set; } 14 | 15 | public CategoryBasicModel[] Categories { get; set; } 16 | 17 | public string[] Tags { get; set; } 18 | 19 | public DateTime Date { get; set; } 20 | 21 | public bool AllowComment { get; set; } 22 | 23 | public Enums.TopicStatus Status { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Widget/AvailableWidgetModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Core.Model.Widget 7 | { 8 | public class AvailableWidgetModel 9 | { 10 | public Enums.WidgetType Type { get; set; } 11 | 12 | public string Name { get; set; } 13 | 14 | public string Icon { get; set; } 15 | 16 | public WidgetConfigModelBase DefaultConfig { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Model/Widget/WidgetModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Core.Model.Widget 8 | { 9 | public class WidgetModel 10 | { 11 | public WidgetType Type { get; set; } 12 | 13 | public WidgetConfigModelBase Config { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("DotNetBlog.Core")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("89065586-c5ef-4ef4-bcd5-63d47e6e3816")] 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Core/Utilities/EncryptHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Core.Utilities 9 | { 10 | public sealed class EncryptHelper 11 | { 12 | public static string MD5(string input) 13 | { 14 | if (input == null) 15 | { 16 | throw new ArgumentNullException("input"); 17 | } 18 | 19 | using (MD5 md5 = System.Security.Cryptography.MD5.Create()) 20 | { 21 | byte[] inputData = Encoding.UTF8.GetBytes(input); 22 | byte[] computedData = md5.ComputeHash(inputData); 23 | 24 | return BitConverter.ToString(computedData).Replace("-", ""); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Controllers/MyController.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core; 2 | using DotNetBlog.Core.Service; 3 | using DotNetBlog.Web.Areas.Api.Models.My; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace DotNetBlog.Web.Areas.Api.Controllers 11 | { 12 | [Route("api/my")] 13 | public class MyController : ControllerBase 14 | { 15 | private ClientManager ClientManager { get; set; } 16 | 17 | private UserService UserService { get; set; } 18 | 19 | public MyController(ClientManager clientManager, UserService userService) 20 | { 21 | this.ClientManager = clientManager; 22 | this.UserService = userService; 23 | } 24 | 25 | [HttpGet("")] 26 | public IActionResult GetMyInfo() 27 | { 28 | var user = this.ClientManager.CurrentUser; 29 | return this.Success(user); 30 | } 31 | 32 | [HttpPost("")] 33 | public async Task EditMyInfo([FromBody]EditMyInfoModel model) 34 | { 35 | if (model == null) 36 | { 37 | return this.InvalidRequest(); 38 | } 39 | 40 | var result = await this.UserService.EditUserInfo(this.ClientManager.CurrentUser.ID, model.Email, model.Nickname); 41 | 42 | if (result.Success) 43 | { 44 | return this.Success(); 45 | } 46 | else 47 | { 48 | return this.Error(result.ErrorMessage); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Controllers/StatisticsController.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Service; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Areas.Api.Controllers 9 | { 10 | [Area("Api")] 11 | [Route("api/statistics")] 12 | [Filters.RequireLoginApiFilter] 13 | public class StatisticsController : ControllerBase 14 | { 15 | private StatisticsService StatisticsService { get; set; } 16 | 17 | public StatisticsController(StatisticsService statisticsService) 18 | { 19 | this.StatisticsService = statisticsService; 20 | } 21 | 22 | [HttpGet("")] 23 | public async Task Index() 24 | { 25 | var model = await this.StatisticsService.GetBlogStatistics(); 26 | 27 | return this.Success(model); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Filters/ErrorHandlerFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using NLog; 8 | using DotNetBlog.Web.Areas.Api.Models; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.AspNetCore.Http; 11 | using Microsoft.AspNetCore.Mvc.Localization; 12 | 13 | namespace DotNetBlog.Web.Areas.Api.Filters 14 | { 15 | public class ErrorHandlerFilter : ExceptionFilterAttribute 16 | { 17 | private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | var L = context.HttpContext.RequestServices.GetService>(); 22 | Logger.Error(context.Exception, context.Exception.Message); 23 | 24 | var apiResponse = new ApiResponse 25 | { 26 | Success = false, 27 | ErrorMessage = L["The server has encountered an error"].Value 28 | }; 29 | 30 | context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; 31 | context.Result = new JsonResult(apiResponse); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Filters/RequireLoginApiFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.AspNetCore.Mvc.Filters; 7 | using System.Net; 8 | using Microsoft.AspNetCore.Mvc.Localization; 9 | 10 | namespace DotNetBlog.Web.Areas.Api.Filters 11 | { 12 | public class RequireLoginApiFilter : DotNetBlog.Web.Filters.RequireLoginFilter 13 | { 14 | protected override void HandleUnauthorizedRequest(ActionExecutingContext context) 15 | { 16 | var L = context.HttpContext.RequestServices.GetService>(); 17 | var controller = context.Controller as Controllers.ControllerBase; 18 | context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 19 | context.Result = controller.Error(L["Please sign in"].Value); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Filters/ValidateRequestApiFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Http; 7 | 8 | namespace DotNetBlog.Web.Areas.Api.Filters 9 | { 10 | public class ValidateRequestApiFilter : DotNetBlog.Web.Filters.ValidateRequestFilter 11 | { 12 | protected override void HandleInvalidRequest(ActionExecutingContext context) 13 | { 14 | var controller = context.Controller as Api.Controllers.ControllerBase; 15 | context.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; 16 | context.Result = controller.InvalidRequest(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/ApiResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.Areas.Api.Models 7 | { 8 | public class ApiResponse 9 | { 10 | public bool Success { get; set; } 11 | 12 | public string ErrorMessage { get; set; } 13 | } 14 | 15 | public class ApiResponse : ApiResponse 16 | { 17 | public T Data { get; set; } 18 | } 19 | 20 | public class PagedApiResponse : ApiResponse 21 | { 22 | public List Data { get; set; } 23 | 24 | public int Total { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Category/RemoveCategoryModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.Areas.Api.Models.Category 7 | { 8 | public class RemoveCategoryModel 9 | { 10 | public int[] IDList { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Category/SaveCategoryModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Category 8 | { 9 | public class SaveCategoryModel 10 | { 11 | [Required] 12 | [StringLength(50)] 13 | public string Name { get; set; } 14 | 15 | [StringLength(200)] 16 | public string Description { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Comment/BatchModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Comment 8 | { 9 | public class BatchModel 10 | { 11 | [Required] 12 | public int[] CommentList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Comment/QueryCommentModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.Areas.Api.Models.Comment 7 | { 8 | public class QueryCommentModel 9 | { 10 | public int PageIndex { get; set; } 11 | 12 | public int PageSize { get; set; } 13 | 14 | public Core.Enums.CommentStatus? Status { get; set; } 15 | 16 | public string Keywords { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Comment/ReplyCommentModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Comment 8 | { 9 | public class ReplyCommentModel 10 | { 11 | public int ReplyTo { get; set; } 12 | 13 | [Required] 14 | public string Content { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Config/AdvanceConfigModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Config 8 | { 9 | public class AdvanceConfigModel 10 | { 11 | [Required] 12 | public string ErrorPageTitle { get; set; } 13 | 14 | [Required] 15 | public string ErrorPageContent { get; set; } 16 | 17 | public string HeaderScript { get; set; } 18 | 19 | public string FooterScript { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Config/BasicConfigModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Config 8 | { 9 | public class BasicConfigModel 10 | { 11 | [Required] 12 | public string Host { get; set; } 13 | 14 | [Required] 15 | public string Title { get; set; } 16 | 17 | public string Description { get; set; } 18 | 19 | [Range(1, 100)] 20 | public int TopicsPerPage { get; set; } 21 | 22 | public bool OnlyShowSummary { get; set; } 23 | 24 | public string Language { get; set; } 25 | 26 | public string Theme { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Config/CommentConfigModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.Areas.Api.Models.Config 7 | { 8 | public class CommentConfigModel 9 | { 10 | public bool AllowComment { get; set; } 11 | 12 | public bool VerifyComment { get; set; } 13 | 14 | public bool TrustAuthenticatedCommentUser { get; set; } 15 | 16 | public bool EnableCommentWebSite { get; set; } 17 | 18 | public int CloseCommentDays { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Config/EmailConfigModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.Areas.Api.Models.Config 7 | { 8 | public class EmailConfigModel 9 | { 10 | public string SmtpEmailAddress { get; set; } 11 | 12 | public string SmtpServer { get; set; } 13 | 14 | public string SmtpUser { get; set; } 15 | 16 | public string SmtpPassword { get; set; } 17 | 18 | public int SmtpPort { get; set; } 19 | 20 | public bool SmtpEnableSSL { get; set; } 21 | 22 | public bool SendEmailWhenComment { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/My/EditMyInfoModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.My 8 | { 9 | public class EditMyInfoModel 10 | { 11 | [Required] 12 | [EmailAddress] 13 | [StringLength(100)] 14 | public string Email { get; set; } 15 | 16 | [Required] 17 | [StringLength(20)] 18 | public string Nickname { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Page/BatchModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Page 8 | { 9 | public class BatchModel 10 | { 11 | [Required] 12 | public int[] PageList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Tag/DeleteTagModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Tag 8 | { 9 | public class DeleteTagModel 10 | { 11 | [Required] 12 | public int[] TagList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Tag/QueryTagModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Tag 8 | { 9 | public class QueryTagModel 10 | { 11 | [Range(1, int.MaxValue)] 12 | public int PageIndex { get; set; } 13 | 14 | [Range(1, 100)] 15 | public int PageSize { get; set; } 16 | 17 | public string Keywords { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Tag/SaveTagModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Tag 8 | { 9 | public class SaveTagModel 10 | { 11 | [Required] 12 | [StringLength(50)] 13 | public string Keyword { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Topic/BatchModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Areas.Api.Models.Topic 8 | { 9 | public class BatchModel 10 | { 11 | [Required] 12 | public int[] TopicList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Topic/QueryTopicModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Enums; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Areas.Api.Models.Topic 9 | { 10 | public class QueryTopicModel 11 | { 12 | [Range(1, int.MaxValue)] 13 | public int PageIndex { get; set; } 14 | 15 | [Range(1, 100)] 16 | public int PageSize { get; set; } 17 | 18 | public string Keywords { get; set; } 19 | 20 | public TopicStatus? Status { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Upload/UploadImageModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Areas.Api.Models.Upload 9 | { 10 | public class UploadImageModel 11 | { 12 | [Required] 13 | public IFormFile File { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Areas/Api/Models/Widget/SaveWidgetModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.Areas.Api.Models.Widget 10 | { 11 | public class SaveWidgetModel 12 | { 13 | public Core.Enums.WidgetType Type { get; set; } 14 | 15 | [Required] 16 | public JObject Config { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/AutoMapperConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using AutoMapper; 6 | using DotNetBlog.Web.Areas.Api.Models.Config; 7 | using DotNetBlog.Core.Model.Setting; 8 | using DotNetBlog.Core.Model.Topic; 9 | using DotNetBlog.Core.Entity; 10 | using DotNetBlog.Core.Model.Page; 11 | 12 | namespace DotNetBlog.Web 13 | { 14 | public sealed class AutoMapperConfig 15 | { 16 | public static void Configure() 17 | { 18 | Mapper.Initialize(config => 19 | { 20 | config.CreateMap(); 21 | config.CreateMap(); 22 | config.CreateMap(); 23 | config.CreateMap(); 24 | config.CreateMap(); 25 | config.CreateMap(); 26 | config.CreateMap(); 27 | config.CreateMap(); 28 | 29 | config.CreateMap().ForMember(dest => dest.Date, map => map.MapFrom(source => source.EditDate)); 30 | config.CreateMap().ForMember(dest => dest.Date, map => map.MapFrom(source => source.EditDate)); 31 | config.CreateMap().ForMember(dest => dest.Date, map => map.MapFrom(source => source.EditDate)); 32 | config.CreateMap(); 33 | config.CreateMap(); 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Controllers/AdminController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.Controllers 8 | { 9 | [Route("admin")] 10 | [Filters.RequireLoginFilter] 11 | [Filters.ErrorHandleFilter] 12 | public class AdminController : Controller 13 | { 14 | [Route("{*path}")] 15 | public IActionResult Index() 16 | { 17 | return this.View(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Filters/ErrorHandleFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using NLog; 3 | 4 | namespace DotNetBlog.Web.Filters 5 | { 6 | public class ErrorHandleFilter : ExceptionFilterAttribute 7 | { 8 | private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); 9 | 10 | public override void OnException(ExceptionContext context) 11 | { 12 | Logger.Error(context.Exception, context.Exception.Message); 13 | 14 | base.OnException(context); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Filters/RequireLoginFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using DotNetBlog.Core; 8 | using Microsoft.AspNetCore.Mvc; 9 | using System.Net; 10 | 11 | namespace DotNetBlog.Web.Filters 12 | { 13 | public class RequireLoginFilter : ActionFilterAttribute 14 | { 15 | public override void OnActionExecuting(ActionExecutingContext context) 16 | { 17 | ClientManager clientManager = context.HttpContext.RequestServices.GetService(); 18 | if (!clientManager.IsLogin) 19 | { 20 | this.HandleUnauthorizedRequest(context); 21 | } 22 | else 23 | { 24 | base.OnActionExecuting(context); 25 | } 26 | } 27 | 28 | protected virtual void HandleUnauthorizedRequest(ActionExecutingContext context) 29 | { 30 | string sourceUrl = null; 31 | if (context.HttpContext.Request.Path.HasValue) 32 | { 33 | sourceUrl = context.HttpContext.Request.Path.Value; 34 | 35 | if (context.HttpContext.Request.QueryString.HasValue) 36 | { 37 | sourceUrl += context.HttpContext.Request.QueryString.Value; 38 | } 39 | } 40 | 41 | context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 42 | 43 | context.Result = new RedirectToActionResult("Login", "Account", new { redirect = sourceUrl }); 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Filters/ValidateRequestFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Http; 8 | 9 | namespace DotNetBlog.Web.Filters 10 | { 11 | public class ValidateRequestFilter : ActionFilterAttribute 12 | { 13 | public override void OnActionExecuting(ActionExecutingContext context) 14 | { 15 | if (!context.ModelState.IsValid) 16 | { 17 | this.HandleInvalidRequest(context); 18 | } 19 | else 20 | { 21 | base.OnActionExecuting(context); 22 | } 23 | } 24 | 25 | protected virtual void HandleInvalidRequest(ActionExecutingContext context) 26 | { 27 | context.Result = new StatusCodeResult(StatusCodes.Status400BadRequest); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Middlewares/ClientManagerMiddleware.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using DotNetBlog.Core; 9 | 10 | namespace DotNetBlog.Web.Middlewares 11 | { 12 | // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project 13 | public class ClientManagerMiddleware 14 | { 15 | private readonly RequestDelegate _next; 16 | 17 | public ClientManagerMiddleware(RequestDelegate next) 18 | { 19 | _next = next; 20 | } 21 | 22 | public Task Invoke(HttpContext httpContext) 23 | { 24 | ClientManager clientManager = httpContext.RequestServices.GetService(); 25 | clientManager.Init(httpContext); 26 | 27 | return _next(httpContext); 28 | } 29 | } 30 | 31 | // Extension method used to add the middleware to the HTTP request pipeline. 32 | public static class ClientManagerMiddlewareExtensions 33 | { 34 | public static IApplicationBuilder UseClientManager(this IApplicationBuilder builder) 35 | { 36 | return builder.UseMiddleware(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/NLog.config: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Hosting; 7 | 8 | namespace DotNetBlog.Web 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | var host = new WebHostBuilder() 15 | .UseKestrel() 16 | .UseContentRoot(Directory.GetCurrentDirectory()) 17 | .UseIISIntegration() 18 | .UseStartup() 19 | #if DEBUG 20 | .UseUrls("http://0.0.0.0:5000") 21 | #endif 22 | .Build(); 23 | 24 | host.Run(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Properties/PublishProfiles/release-publish.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding(SupportsShouldProcess=$true)] 2 | param($publishProperties=@{}, $packOutput, $pubProfilePath) 3 | 4 | # to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327 5 | 6 | try{ 7 | if ($publishProperties['ProjectGuid'] -eq $null){ 8 | $publishProperties['ProjectGuid'] = '89f9b8c8-2f34-41cf-b39e-c23935afadc8' 9 | } 10 | 11 | $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1' 12 | Import-Module $publishModulePath -DisableNameChecking -Force 13 | 14 | # call Publish-AspNet to perform the publish operation 15 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath 16 | } 17 | catch{ 18 | "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error 19 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Properties/PublishProfiles/release.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | netcoreapp1.0 15 | True 16 | .\bin\Release\PublishOutput 17 | True 18 | 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:10142/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "DotNetBlog.Web": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "launchUrl": "http://localhost:10142", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Web/TagHelpers/BlogTitleTagHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Razor.TagHelpers; 6 | using Microsoft.AspNetCore.Mvc.ViewFeatures; 7 | using Microsoft.AspNetCore.Mvc.Rendering; 8 | using DotNetBlog.Core.Model.Setting; 9 | 10 | namespace DotNetBlog.Web.TagHelpers 11 | { 12 | [HtmlTargetElement("blog-title")] 13 | public class BlogTitleTagHelper : TagHelper 14 | { 15 | private SettingModel Setting { get; set; } 16 | 17 | public BlogTitleTagHelper(SettingModel setting) 18 | { 19 | Setting = setting; 20 | } 21 | 22 | [ViewContext] 23 | public ViewContext ViewContext { get; set; } 24 | 25 | public override void Process(TagHelperContext context, TagHelperOutput output) 26 | { 27 | output.TagName = "title"; 28 | 29 | string title; 30 | 31 | string customTitle = ViewContext.ViewBag.Title as string; 32 | if (string.IsNullOrWhiteSpace(customTitle)) 33 | { 34 | title = Setting.Title; 35 | } 36 | else 37 | { 38 | title = $"{customTitle} - {Setting.Title}"; 39 | } 40 | 41 | output.Content.SetContent(title); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/TagHelpers/MarkdownTagHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Razor.Runtime.TagHelpers; 6 | using Microsoft.AspNetCore.Razor.TagHelpers; 7 | using CommonMark; 8 | using Microsoft.AspNetCore.Mvc.Rendering; 9 | using Microsoft.AspNetCore.Mvc.ViewFeatures; 10 | 11 | namespace DotNetBlog.Web.TagHelpers 12 | { 13 | // You may need to install the Microsoft.AspNetCore.Razor.Runtime package into your project 14 | [HtmlTargetElement("markdown")] 15 | public class MarkdownTagHelper : TagHelper 16 | { 17 | [HtmlAttributeName("content")] 18 | public string Content { get; set; } 19 | 20 | public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) 21 | { 22 | string content = null; 23 | 24 | if (this.Content != null) 25 | { 26 | content = this.Content; 27 | } 28 | else 29 | { 30 | content = (await output.GetChildContentAsync()).GetContent(); 31 | } 32 | 33 | output.TagName = ""; 34 | 35 | string html = CommonMarkConverter.Convert(content); 36 | 37 | output.Content.SetHtmlContent(html); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/TagHelpers/VisibleTagHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Razor.Runtime.TagHelpers; 6 | using Microsoft.AspNetCore.Razor.TagHelpers; 7 | 8 | namespace DotNetBlog.Web.TagHelpers 9 | { 10 | // You may need to install the Microsoft.AspNetCore.Razor.Runtime package into your project 11 | [HtmlTargetElement(Attributes = "condition")] 12 | [HtmlTargetElement("visible")] 13 | public class VisibleTagHelper : TagHelper 14 | { 15 | [HtmlAttributeName("condition")] 16 | public bool Condition { get; set; } 17 | 18 | public override void Process(TagHelperContext context, TagHelperOutput output) 19 | { 20 | if (output.TagName == "visible") 21 | { 22 | output.TagName = ""; 23 | } 24 | 25 | if (!this.Condition) 26 | { 27 | output.TagName = ""; 28 | output.Content.SetHtmlContent(""); 29 | } 30 | else 31 | { 32 | base.Process(context, output); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Account/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | @RenderBody() 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Account/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Web.ViewModels.Account -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Exception/Error.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Web.ViewModels.Exception 2 | @model ErrorViewModel 3 | @inject IViewLocalizer L 4 | 5 |
    6 |

    500

    7 | 8 |
    9 |

    @Model.Title

    10 | 11 |

    12 | @Model.Content 13 |

    14 |

    15 | @L["You can"] @L["return to home page"], @L["or search for other resources"] 16 |

    17 | 18 |
    19 |
    20 | 21 | 22 |
    23 | 26 |
    27 |
    28 |
    29 |
    30 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Exception/NotFound.cshtml: -------------------------------------------------------------------------------- 1 | @inject IViewLocalizer L 2 | 3 |
    4 |

    404

    5 | 6 |
    7 |

    Oops! Page not found.

    8 | 9 |

    10 | @L["Access to the page does not exist, you can"]@L["return to the home page"], @L["or search for other resources"] 11 |

    12 | 13 |
    14 |
    15 | 16 | 17 |
    18 | 21 |
    22 |
    23 |
    24 |
    25 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Exception/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | @RenderBody() 13 | 14 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Category.cshtml: -------------------------------------------------------------------------------- 1 | @model CategoryPageViewModel 2 | 3 | @Html.Partial("_TopicList", Model.TopicList.Data) 4 | 5 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/AdministrationWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @inject ClientManager clientManager 2 | @inject IViewLocalizer L 3 | @{ 4 | var config = ViewBag.Config as AdministrationWidgetConfigModel; 5 | } 6 | 7 | 8 |
    9 |

    @config.Title

    10 | 20 |
    21 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/CategoryWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Category 2 | @inject IViewLocalizer L 3 | 4 | @model List 5 | 6 | @{ 7 | var config = ViewBag.Config as CategoryWidgetConfigModel; 8 | } 9 | 10 |
    11 |

    @config.Title

    12 |
    13 | 24 |
    25 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/MonthStatisticsWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Topic 2 | @model List 3 | @inject IViewLocalizer L 4 | 5 | @{ 6 | var groupList = Model.GroupBy(t => t.Month.Year); 7 | var config = ViewBag.Config as MonthStatisticeWidgetConfigModel; 8 | } 9 | 10 |
    11 |

    @config.Title

    12 |
    13 |
      14 | @foreach (var year in groupList) 15 | { 16 |
    • 17 | @year.Key 18 |
        19 | @foreach (var month in year) 20 | { 21 |
      • @L["MM", month.Month] (@month.Topics.Published)
      • 22 | } 23 |
      24 |
    • 25 | } 26 |
    27 |
    28 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/PageListNav/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model List 2 | 3 | @{ 4 | var root = Model.Where(t => t.Parent == null); 5 | } 6 | 7 | 8 | @foreach (var page in root) 9 | { 10 | var children = Model.Where(t => t.Parent != null && t.Parent.ID == page.ID); 11 | 21 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/PageWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model List 2 | @{ 3 | var config = ViewBag.Config as PageWidgetConfigModel; 4 | } 5 | 6 |
    7 |

    @config.Title

    8 |
    9 |
      10 | @foreach (var page in Model) 11 | { 12 |
    • 13 | @page.Title 14 |
    • 15 | } 16 |
    17 |
    18 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/RecentCommentWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Comment 2 | @model List 3 | @inject IViewLocalizer L 4 | @{ 5 | var config = ViewBag.Config as RecentCommentWidgetConfigModel; 6 | } 7 | 8 |
    9 |

    @config.Title

    10 |
    11 |
      12 | @foreach (var comment in Model) 13 | { 14 |
    • 15 | @comment.Topic.Title (@comment.Topic.Comments.Approved) 16 |
      @comment.Name @L["Wrote"]: @comment.Content 17 |
    • 18 | } 19 | @*
    • 20 | 21 | 评论RSS 22 | 23 |
    • *@ 24 |
    25 |
    26 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/RecentTopicWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Topic 2 | @model List 3 | @{ 4 | var config = ViewBag.Config as RecentTopicWidgetConfigModel; 5 | } 6 | 7 |
    8 |

    @config.Title

    9 |
    10 | 20 |
    21 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/SearchWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @inject IViewLocalizer L 2 | @{ 3 | var config = ViewBag.Config as SearchWidgetConfigModel; 4 | } 5 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/TagWidget/Default.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Tag 2 | @model List 3 | @{ 4 | var config = ViewBag.Config as TagWidgetConfigModel; 5 | } 6 | 7 |
    8 |

    @config.Title

    9 |
    10 |
      11 | @foreach (var tag in Model) 12 | { 13 |
    • @tag.Keyword
    • 14 | } 15 |
    16 |
    17 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/Widgets/Default.cshtml: -------------------------------------------------------------------------------- 1 | @inject ClientManager clientManager 2 | @using DotNetBlog.Core.Model.Widget 3 | @model List 4 | 5 |
    6 | @foreach(var widget in Model) 7 | { 8 | @await Component.InvokeAsync($"{widget.Type}Widget", new { config = widget.Config }) 9 | } 10 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Components/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Core.Model.Widget -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IndexPageViewModel 2 | 3 | @Html.Partial("_TopicList", Model.TopicList.Data) 4 | 5 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Month.cshtml: -------------------------------------------------------------------------------- 1 | @model MonthPageViewModel 2 | 3 | @Html.Partial("_TopicList", Model.TopicList.Data) 4 | 5 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Notice.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Web.ViewModels.Home 2 | @model NoticePageViewModel 3 | @inject IViewLocalizer L 4 | @{ 5 | string className; 6 | switch(Model.MessageType) 7 | { 8 | case NoticePageViewModel.NoticeMessageType.Info: 9 | className = "info"; 10 | break; 11 | case NoticePageViewModel.NoticeMessageType.Error: 12 | className = "danger"; 13 | break; 14 | default: 15 | className = "success"; 16 | break; 17 | } 18 | } 19 | 20 |
    21 |
    22 |
    23 | @Model.Message 24 |
    25 | 26 |

    27 | @L["Go back to the last page"] 28 |

    29 |
    30 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Page.cshtml: -------------------------------------------------------------------------------- 1 | @model DotNetBlog.Core.Model.Page.PageModel 2 | @inject ClientManager clientManager 3 | @inject IViewLocalizer L 4 | 5 |
    6 |

    @Model.Title

    7 |
    8 | 9 |
    10 |
    11 | @L["Edit"] 12 |
    13 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Search.cshtml: -------------------------------------------------------------------------------- 1 | @model SearchPageViewModel 2 | @inject IViewLocalizer L 3 |
    4 |

    @L["Search result"]: '@Model.Keywords'

    5 |

    @L["Enter the keyword for search"]

    6 | 12 | 13 | @foreach (var topic in Model.TopicList.Data) 14 | { 15 |
    16 | @topic.Title 17 | @topic.Summary 18 | 19 | @L["Category"] : 20 | @foreach (var category in topic.Categories) 21 | { 22 | @category.Name 23 | @(" ") 24 | } 25 |
    26 | @L["Tag"] : 27 | @foreach (var tag in topic.Tags) 28 | { 29 | @tag 30 | @(" ") 31 | } 32 |
    33 |
    34 | } 35 | 36 |
    -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/Tag.cshtml: -------------------------------------------------------------------------------- 1 | @model TagPageViewModel 2 | 3 | @Html.Partial("_TopicList", Model.TopicList.Data) 4 | 5 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/Home/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using DotNetBlog.Web.ViewModels.Home -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 2 | @addTagHelper *, DotNetBlog.Web 3 | @using Microsoft.AspNetCore.Mvc.Localization 4 | @using DotNetBlog.Core 5 | @using DotNetBlog.Core.Entity 6 | @using DotNetBlog.Core.Model 7 | @using DotNetBlog.Core.Model.Setting 8 | @inject DotNetBlog.Core.Model.Theme.ThemeModel Theme -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Themes/default/theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Default Theme", 3 | "description": "-", 4 | "author": "BlogEngine", 5 | "authorUrl": "https://github.com/scheshan/DotNetBlog", 6 | "authorEmail": "" 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewComponents/PageListNav.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Service; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.ViewComponents 9 | { 10 | public class PageListNav : ViewComponent 11 | { 12 | private PageService PageService { get; set; } 13 | 14 | public PageListNav(PageService pageService) 15 | { 16 | this.PageService = pageService; 17 | } 18 | 19 | public async Task InvokeAsync() 20 | { 21 | var pageList = await this.PageService.QueryPublished(); 22 | return this.View(pageList); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewComponents/Widgets.cs: -------------------------------------------------------------------------------- 1 |  2 | using DotNetBlog.Core.Service; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.ViewComponents 10 | { 11 | public class Widgets : ViewComponent 12 | { 13 | private WidgetService WidgetService { get; set; } 14 | 15 | public Widgets(WidgetService widgetService) 16 | { 17 | this.WidgetService = widgetService; 18 | } 19 | 20 | public async Task InvokeAsync() 21 | { 22 | var widgetList = await this.WidgetService.Query(); 23 | 24 | return this.View(widgetList); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Account/ChangePasswordModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.ViewModels.Account 8 | { 9 | public class ChangePasswordModel 10 | { 11 | [Required] 12 | public string OldPassword { get; set; } 13 | 14 | [Required] 15 | [StringLength(20, MinimumLength = 6)] 16 | public string Password { get; set; } 17 | 18 | [Required] 19 | public string ConfirmPassword { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Account/ChangePasswordViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Account 7 | { 8 | public class ChangePasswordViewModel 9 | { 10 | public string ErrorMessage { get; set; } 11 | 12 | public string SuccessMessage { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Account/LoginModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.ViewModels.Account 8 | { 9 | public class LoginModel 10 | { 11 | [Required] 12 | public string UserName { get; set; } 13 | 14 | [Required] 15 | public string Password { get; set; } 16 | 17 | public bool RememberMe { get; set; } 18 | 19 | public string Redirect { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Account/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Account 7 | { 8 | public class LoginViewModel 9 | { 10 | public LoginModel Model { get; set; } 11 | 12 | public string ErrorMessage { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Exception/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Exception 7 | { 8 | public class ErrorViewModel 9 | { 10 | public string Title { get; set; } 11 | 12 | public string Content { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/CategoryPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Category; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.ViewModels.Home 8 | { 9 | public class CategoryPageViewModel 10 | { 11 | public CategoryModel Category { get; set; } 12 | 13 | public TopicListModel TopicList { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/CommentFormModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Home 7 | { 8 | public class CommentFormModel 9 | { 10 | public string Name { get; set; } 11 | 12 | public string Email { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/CommentListViewModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Comment; 2 | using DotNetBlog.Core.Model.Topic; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.ViewModels.Home 9 | { 10 | public class CommentListViewModel 11 | { 12 | /// 13 | /// 是否允许评论 14 | /// 15 | public bool AllowComment { get; set; } 16 | 17 | /// 18 | /// 所有评论列表 19 | /// 20 | public List AllCommentList { get; set; } 21 | 22 | /// 23 | /// 适合本页用的评论列表 24 | /// 25 | public List CommentList { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/IndexPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Topic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.ViewModels.Home 8 | { 9 | public class IndexPageViewModel 10 | { 11 | public TopicListModel TopicList { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/MonthPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Home 7 | { 8 | public class MonthPageViewModel 9 | { 10 | public int Year { get; set; } 11 | 12 | public int Month { get; set; } 13 | 14 | public TopicListModel TopicList { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/NoticePageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Home 7 | { 8 | public class NoticePageViewModel 9 | { 10 | public string Message { get; set; } 11 | 12 | public string RedirectUrl { get; set; } 13 | 14 | public NoticeMessageType MessageType { get; set; } 15 | 16 | public enum NoticeMessageType 17 | { 18 | Success = 1, 19 | Error = 2, 20 | Info = 3 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/SearchPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Home 7 | { 8 | public class SearchPageViewModel 9 | { 10 | public string Keywords { get; set; } 11 | 12 | public TopicListModel TopicList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/TagPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DotNetBlog.Web.ViewModels.Home 7 | { 8 | public class TagPageViewModel 9 | { 10 | public string Tag { get; set; } 11 | 12 | public TopicListModel TopicList { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/TopicListModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Topic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DotNetBlog.Web.ViewModels.Home 8 | { 9 | public class TopicListModel 10 | { 11 | public int PageIndex { get; set; } 12 | 13 | public int PageSize { get; set; } 14 | 15 | public List Data { get; set; } 16 | 17 | public int Total { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Home/TopicPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Comment; 2 | using DotNetBlog.Core.Model.Topic; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.ViewModels.Home 9 | { 10 | public class TopicPageViewModel 11 | { 12 | public bool AllowComment { get; set; } 13 | 14 | public CommentFormModel CommentForm { get; set; } 15 | 16 | public TopicModel Topic { get; set; } 17 | 18 | public TopicModel PrevTopic { get; set; } 19 | 20 | public TopicModel NextTopic { get; set; } 21 | 22 | public List RelatedTopicList { get; set; } 23 | 24 | public List CommentList { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/ViewModels/Install/IndexViewModel.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Install; 2 | using Microsoft.AspNetCore.Mvc.Rendering; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.ViewModels.Install 9 | { 10 | public class IndexViewModel 11 | { 12 | public string ErrorMessage { get; set; } 13 | 14 | public SelectList LanguageList { get; set; } 15 | 16 | public InstallModel Model { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/AdministrationWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Widgets 9 | { 10 | public class AdministrationWidget : ViewComponent 11 | { 12 | public IViewComponentResult Invoke(AdministrationWidgetConfigModel config) 13 | { 14 | ViewBag.Config = config; 15 | 16 | return View(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/CategoryWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Category; 2 | using DotNetBlog.Core.Model.Widget; 3 | using DotNetBlog.Core.Service; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace DotNetBlog.Web.Widgets 11 | { 12 | public class CategoryWidget : ViewComponent 13 | { 14 | private CategoryService CategoryService { get; set; } 15 | 16 | public CategoryWidget(CategoryService categoryService) 17 | { 18 | CategoryService = categoryService; 19 | } 20 | 21 | public async Task InvokeAsync(CategoryWidgetConfigModel config) 22 | { 23 | ViewBag.Config = config; 24 | 25 | List categoryList = await CategoryService.All(); 26 | return this.View(categoryList); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/MonthStatisticsWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using DotNetBlog.Core.Service; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.Widgets 10 | { 11 | public class MonthStatisticsWidget : ViewComponent 12 | { 13 | private TopicService TopicService { get; set; } 14 | 15 | public MonthStatisticsWidget(TopicService topicService) 16 | { 17 | TopicService = topicService; 18 | } 19 | 20 | public async Task InvokeAsync(MonthStatisticeWidgetConfigModel config) 21 | { 22 | ViewBag.Config = config; 23 | 24 | var list = await TopicService.QueryMonthStatistics(); 25 | 26 | return View(list); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/PageWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using DotNetBlog.Core.Service; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.Widgets 10 | { 11 | public class PageWidget : ViewComponent 12 | { 13 | private PageService PageService { get; set; } 14 | 15 | public PageWidget(PageService pageService) 16 | { 17 | this.PageService = pageService; 18 | } 19 | 20 | public async Task InvokeAsync(PageWidgetConfigModel config) 21 | { 22 | ViewBag.Config = config; 23 | 24 | var pageList = await this.PageService.QueryPublished(); 25 | return View(pageList); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/RecentCommentWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using DotNetBlog.Core.Service; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.Widgets 10 | { 11 | public class RecentCommentWidget : ViewComponent 12 | { 13 | private CommentService CommentService { get; set; } 14 | 15 | public RecentCommentWidget(CommentService commentService) 16 | { 17 | this.CommentService = commentService; 18 | } 19 | 20 | public async Task InvokeAsync(RecentCommentWidgetConfigModel config) 21 | { 22 | ViewBag.Config = config; 23 | 24 | var commentList = await this.CommentService.QueryLatest(config.Number); 25 | return View(commentList); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/RecentTopicWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Service; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Widgets 9 | { 10 | public class RecentTopicWidget : ViewComponent 11 | { 12 | private TopicService TopicService { get; set; } 13 | 14 | public RecentTopicWidget(TopicService topicService) 15 | { 16 | TopicService = topicService; 17 | } 18 | 19 | public async Task InvokeAsync(Core.Model.Widget.RecentTopicWidgetConfigModel config) 20 | { 21 | ViewBag.Config = config; 22 | 23 | var topicList = await TopicService.QueryRecent(config.Number, config.Category); 24 | 25 | return View(topicList); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/SearchWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using Microsoft.AspNetCore.Mvc; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetBlog.Web.Widgets 9 | { 10 | public class SearchWidget : ViewComponent 11 | { 12 | public SearchWidget() 13 | { 14 | 15 | } 16 | 17 | public IViewComponentResult Invoke(SearchWidgetConfigModel config) 18 | { 19 | ViewBag.Config = config; 20 | 21 | return View(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/Widgets/TagWidget.cs: -------------------------------------------------------------------------------- 1 | using DotNetBlog.Core.Model.Widget; 2 | using DotNetBlog.Core.Service; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace DotNetBlog.Web.Widgets 10 | { 11 | public class TagWidget : ViewComponent 12 | { 13 | private TagService TagService { get; set; } 14 | 15 | public TagWidget(TagService tagService) 16 | { 17 | TagService = tagService; 18 | } 19 | 20 | public async Task InvokeAsync(TagWidgetConfigModel config) 21 | { 22 | ViewBag.Config = config; 23 | 24 | var query = (await TagService.All()).AsQueryable(); 25 | 26 | query = query.Where(t => t.Topics.Published >= config.MinTopicNumber) 27 | .OrderByDescending(t => t.Topics.Published); 28 | 29 | if (config.Number.HasValue) 30 | { 31 | query = query.Take(config.Number.Value); 32 | } 33 | 34 | var tagList = query.ToList(); 35 | 36 | return View(tagList); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": "sqlite", 3 | "connectionString": "DataSource=App_Data/blog.db" 4 | //"database": "sqlserver", 5 | //"connectionString": "server=.\\SqlServer2008;database=DotNetBlog;uid=sa;pwd=123456" 6 | } 7 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/runtimeconfig.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "gcServer": true 3 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Web/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/carrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/carrow.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/Administration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/Administration.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/Category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/Category.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/MonthStatistics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/MonthStatistics.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/Page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/Page.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/RecentComment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/RecentComment.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/RecentTopic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/RecentTopic.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/Search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/Search.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/images/widget/Tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/images/widget/Tag.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/css/editormd.logo.min.css: -------------------------------------------------------------------------------- 1 | /*! Editor.md v1.5.0 | editormd.logo.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ 2 | /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3} -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.eot -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.ttf -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/editormd-logo.woff -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading.gif -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading@2x.gif -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading@3x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/loading@3x.gif -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-16x16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-16x16.ico -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-24x24.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-24x24.ico -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-32x32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-32x32.ico -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-48x48.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-48x48.ico -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-64x64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-favicon-64x64.ico -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-114x114.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-120x120.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-144x144.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-16x16.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-180x180.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-240x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-240x240.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-24x24.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-320x320.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-320x320.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-32x32.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-48x48.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-57x57.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-64x64.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-72x72.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/editormd-logo-96x96.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/vi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scheshan/DotNetBlog/c371b8166a210ccb54c965f7c09e54c099a73ef9/src/DotNetBlog.Web/wwwroot/lib/editor.md/images/logos/vi.png -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 by Marijn Haverbeke and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/README.md: -------------------------------------------------------------------------------- 1 | # CodeMirror 2 | [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) 3 | [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) 4 | [Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/) 5 | 6 | CodeMirror is a JavaScript component that provides a code editor in 7 | the browser. When a mode is available for the language you are coding 8 | in, it will color your code, and optionally help with indentation. 9 | 10 | The project page is http://codemirror.net 11 | The manual is at http://codemirror.net/doc/manual.html 12 | The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md) 13 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/dialog/dialog.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-dialog { 2 | position: absolute; 3 | left: 0; right: 0; 4 | background: white; 5 | z-index: 15; 6 | padding: .1em .8em; 7 | overflow: hidden; 8 | color: #333; 9 | } 10 | 11 | .CodeMirror-dialog-top { 12 | border-bottom: 1px solid #eee; 13 | top: 0; 14 | } 15 | 16 | .CodeMirror-dialog-bottom { 17 | border-top: 1px solid #eee; 18 | bottom: 0; 19 | } 20 | 21 | .CodeMirror-dialog input { 22 | border: none; 23 | outline: none; 24 | background: transparent; 25 | width: 20em; 26 | color: inherit; 27 | font-family: monospace; 28 | } 29 | 30 | .CodeMirror-dialog button { 31 | font-size: 70%; 32 | } 33 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/display/fullscreen.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-fullscreen { 2 | position: fixed; 3 | top: 0; left: 0; right: 0; bottom: 0; 4 | height: auto; 5 | z-index: 9; 6 | } 7 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/display/fullscreen.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { 15 | if (old == CodeMirror.Init) old = false; 16 | if (!old == !val) return; 17 | if (val) setFullscreen(cm); 18 | else setNormal(cm); 19 | }); 20 | 21 | function setFullscreen(cm) { 22 | var wrap = cm.getWrapperElement(); 23 | cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, 24 | width: wrap.style.width, height: wrap.style.height}; 25 | wrap.style.width = ""; 26 | wrap.style.height = "auto"; 27 | wrap.className += " CodeMirror-fullscreen"; 28 | document.documentElement.style.overflow = "hidden"; 29 | cm.refresh(); 30 | } 31 | 32 | function setNormal(cm) { 33 | var wrap = cm.getWrapperElement(); 34 | wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); 35 | document.documentElement.style.overflow = ""; 36 | var info = cm.state.fullScreenRestore; 37 | wrap.style.width = info.width; wrap.style.height = info.height; 38 | window.scrollTo(info.scrollLeft, info.scrollTop); 39 | cm.refresh(); 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/edit/trailingspace.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { 13 | if (prev == CodeMirror.Init) prev = false; 14 | if (prev && !val) 15 | cm.removeOverlay("trailingspace"); 16 | else if (!prev && val) 17 | cm.addOverlay({ 18 | token: function(stream) { 19 | for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} 20 | if (i > stream.pos) { stream.pos = i; return null; } 21 | stream.pos = l; 22 | return "trailingspace"; 23 | }, 24 | name: "trailingspace" 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/fold/foldgutter.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-foldmarker { 2 | color: blue; 3 | text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; 4 | font-family: arial; 5 | line-height: .3; 6 | cursor: pointer; 7 | } 8 | .CodeMirror-foldgutter { 9 | width: .7em; 10 | } 11 | .CodeMirror-foldgutter-open, 12 | .CodeMirror-foldgutter-folded { 13 | cursor: pointer; 14 | } 15 | .CodeMirror-foldgutter-open:after { 16 | content: "\25BE"; 17 | } 18 | .CodeMirror-foldgutter-folded:after { 19 | content: "\25B8"; 20 | } 21 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/hint/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | max-width: 19em; 29 | overflow: hidden; 30 | white-space: pre; 31 | color: black; 32 | cursor: pointer; 33 | } 34 | 35 | li.CodeMirror-hint-active { 36 | background: #08f; 37 | color: white; 38 | } 39 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js 5 | 6 | // declare global: coffeelint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "coffeescript", function(text) { 19 | var found = []; 20 | var parseError = function(err) { 21 | var loc = err.lineNumber; 22 | found.push({from: CodeMirror.Pos(loc-1, 0), 23 | to: CodeMirror.Pos(loc, 0), 24 | severity: err.level, 25 | message: err.message}); 26 | }; 27 | try { 28 | var res = coffeelint.lint(text); 29 | for(var i = 0; i < res.length; i++) { 30 | parseError(res[i]); 31 | } 32 | } catch(e) { 33 | found.push({from: CodeMirror.Pos(e.location.first_line, 0), 34 | to: CodeMirror.Pos(e.location.last_line, e.location.last_column), 35 | severity: 'error', 36 | message: e.message}); 37 | } 38 | return found; 39 | }); 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/lint/css-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Depends on csslint.js from https://github.com/stubbornella/csslint 5 | 6 | // declare global: CSSLint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "css", function(text) { 19 | var found = []; 20 | if (!window.CSSLint) return found; 21 | var results = CSSLint.verify(text), messages = results.messages, message = null; 22 | for ( var i = 0; i < messages.length; i++) { 23 | message = messages[i]; 24 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; 25 | found.push({ 26 | from: CodeMirror.Pos(startLine, startCol), 27 | to: CodeMirror.Pos(endLine, endCol), 28 | message: message.message, 29 | severity : message.type 30 | }); 31 | } 32 | return found; 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/lint/json-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Depends on jsonlint.js from https://github.com/zaach/jsonlint 5 | 6 | // declare global: jsonlint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "json", function(text) { 19 | var found = []; 20 | jsonlint.parseError = function(str, hash) { 21 | var loc = hash.loc; 22 | found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), 23 | to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), 24 | message: str}); 25 | }; 26 | try { jsonlint.parse(text); } 27 | catch(e) {} 28 | return found; 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/lint/yaml-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | // Depends on js-yaml.js from https://github.com/nodeca/js-yaml 15 | 16 | // declare global: jsyaml 17 | 18 | CodeMirror.registerHelper("lint", "yaml", function(text) { 19 | var found = []; 20 | try { jsyaml.load(text); } 21 | catch(e) { 22 | var loc = e.mark; 23 | found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message }); 24 | } 25 | return found; 26 | }); 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/mode/multiplex_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | CodeMirror.defineMode("markdown_with_stex", function(){ 6 | var inner = CodeMirror.getMode({}, "stex"); 7 | var outer = CodeMirror.getMode({}, "markdown"); 8 | 9 | var innerOptions = { 10 | open: '$', 11 | close: '$', 12 | mode: inner, 13 | delimStyle: 'delim', 14 | innerStyle: 'inner' 15 | }; 16 | 17 | return CodeMirror.multiplexingMode(outer, innerOptions); 18 | }); 19 | 20 | var mode = CodeMirror.getMode({}, "markdown_with_stex"); 21 | 22 | function MT(name) { 23 | test.mode( 24 | name, 25 | mode, 26 | Array.prototype.slice.call(arguments, 1), 27 | 'multiplexing'); 28 | } 29 | 30 | MT( 31 | "stexInsideMarkdown", 32 | "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); 33 | })(); 34 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/runmode/colorize.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("./runmode")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "./runmode"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; 15 | 16 | function textContent(node, out) { 17 | if (node.nodeType == 3) return out.push(node.nodeValue); 18 | for (var ch = node.firstChild; ch; ch = ch.nextSibling) { 19 | textContent(ch, out); 20 | if (isBlock.test(node.nodeType)) out.push("\n"); 21 | } 22 | } 23 | 24 | CodeMirror.colorize = function(collection, defaultMode) { 25 | if (!collection) collection = document.body.getElementsByTagName("pre"); 26 | 27 | for (var i = 0; i < collection.length; ++i) { 28 | var node = collection[i]; 29 | var mode = node.getAttribute("data-lang") || defaultMode; 30 | if (!mode) continue; 31 | 32 | var text = []; 33 | textContent(node, text); 34 | node.innerHTML = ""; 35 | CodeMirror.runMode(text.join(""), mode, node); 36 | 37 | node.className += " cm-s-default"; 38 | } 39 | }; 40 | }); 41 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/scroll/scrollpastend.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { 15 | if (old && old != CodeMirror.Init) { 16 | cm.off("change", onChange); 17 | cm.off("refresh", updateBottomMargin); 18 | cm.display.lineSpace.parentNode.style.paddingBottom = ""; 19 | cm.state.scrollPastEndPadding = null; 20 | } 21 | if (val) { 22 | cm.on("change", onChange); 23 | cm.on("refresh", updateBottomMargin); 24 | updateBottomMargin(cm); 25 | } 26 | }); 27 | 28 | function onChange(cm, change) { 29 | if (CodeMirror.changeEnd(change).line == cm.lastLine()) 30 | updateBottomMargin(cm); 31 | } 32 | 33 | function updateBottomMargin(cm) { 34 | var padding = ""; 35 | if (cm.lineCount() > 1) { 36 | var totalH = cm.display.scroller.clientHeight - 30, 37 | lastLineH = cm.getLineHandle(cm.lastLine()).height; 38 | padding = (totalH - lastLineH) + "px"; 39 | } 40 | if (cm.state.scrollPastEndPadding != padding) { 41 | cm.state.scrollPastEndPadding = padding; 42 | cm.display.lineSpace.parentNode.style.paddingBottom = padding; 43 | cm.setSize(); 44 | } 45 | } 46 | }); 47 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/scroll/simplescrollbars.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div { 2 | position: absolute; 3 | background: #ccc; 4 | -moz-box-sizing: border-box; 5 | box-sizing: border-box; 6 | border: 1px solid #bbb; 7 | border-radius: 2px; 8 | } 9 | 10 | .CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical { 11 | position: absolute; 12 | z-index: 6; 13 | background: #eee; 14 | } 15 | 16 | .CodeMirror-simplescroll-horizontal { 17 | bottom: 0; left: 0; 18 | height: 8px; 19 | } 20 | .CodeMirror-simplescroll-horizontal div { 21 | bottom: 0; 22 | height: 100%; 23 | } 24 | 25 | .CodeMirror-simplescroll-vertical { 26 | right: 0; top: 0; 27 | width: 8px; 28 | } 29 | .CodeMirror-simplescroll-vertical div { 30 | right: 0; 31 | width: 100%; 32 | } 33 | 34 | 35 | .CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler { 36 | display: none; 37 | } 38 | 39 | .CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div { 40 | position: absolute; 41 | background: #bcd; 42 | border-radius: 3px; 43 | } 44 | 45 | .CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical { 46 | position: absolute; 47 | z-index: 6; 48 | } 49 | 50 | .CodeMirror-overlayscroll-horizontal { 51 | bottom: 0; left: 0; 52 | height: 6px; 53 | } 54 | .CodeMirror-overlayscroll-horizontal div { 55 | bottom: 0; 56 | height: 100%; 57 | } 58 | 59 | .CodeMirror-overlayscroll-vertical { 60 | right: 0; top: 0; 61 | width: 6px; 62 | } 63 | .CodeMirror-overlayscroll-vertical div { 64 | right: 0; 65 | width: 100%; 66 | } 67 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/search/matchesonscrollbar.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-search-match { 2 | background: gold; 3 | border-top: 1px solid orange; 4 | border-bottom: 1px solid orange; 5 | -moz-box-sizing: border-box; 6 | box-sizing: border-box; 7 | opacity: .5; 8 | } 9 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/addon/tern/worker.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // declare global: tern, server 5 | 6 | var server; 7 | 8 | this.onmessage = function(e) { 9 | var data = e.data; 10 | switch (data.type) { 11 | case "init": return startServer(data.defs, data.plugins, data.scripts); 12 | case "add": return server.addFile(data.name, data.text); 13 | case "del": return server.delFile(data.name); 14 | case "req": return server.request(data.body, function(err, reqData) { 15 | postMessage({id: data.id, body: reqData, err: err && String(err)}); 16 | }); 17 | case "getFile": 18 | var c = pending[data.id]; 19 | delete pending[data.id]; 20 | return c(data.err, data.text); 21 | default: throw new Error("Unknown message type: " + data.type); 22 | } 23 | }; 24 | 25 | var nextId = 0, pending = {}; 26 | function getFile(file, c) { 27 | postMessage({type: "getFile", name: file, id: ++nextId}); 28 | pending[nextId] = c; 29 | } 30 | 31 | function startServer(defs, plugins, scripts) { 32 | if (scripts) importScripts.apply(null, scripts); 33 | 34 | server = new tern.Server({ 35 | getFile: getFile, 36 | async: true, 37 | defs: defs, 38 | plugins: plugins 39 | }); 40 | } 41 | 42 | var console = { 43 | log: function(v) { postMessage({type: "debug", message: v}); } 44 | }; 45 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror", 3 | "version":"5.0.0", 4 | "main": ["lib/codemirror.js", "lib/codemirror.css"], 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components", 9 | "bin", 10 | "demo", 11 | "doc", 12 | "test", 13 | "index.html", 14 | "package.json" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/diff/diff.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineMode("diff", function() { 15 | 16 | var TOKEN_NAMES = { 17 | '+': 'positive', 18 | '-': 'negative', 19 | '@': 'meta' 20 | }; 21 | 22 | return { 23 | token: function(stream) { 24 | var tw_pos = stream.string.search(/[\t ]+?$/); 25 | 26 | if (!stream.sol() || tw_pos === 0) { 27 | stream.skipToEnd(); 28 | return ("error " + ( 29 | TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, ''); 30 | } 31 | 32 | var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd(); 33 | 34 | if (tw_pos === -1) { 35 | stream.skipToEnd(); 36 | } else { 37 | stream.pos = tw_pos; 38 | } 39 | 40 | return token_name; 41 | } 42 | }; 43 | }); 44 | 45 | CodeMirror.defineMIME("text/x-diff", "diff"); 46 | 47 | }); 48 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/ecl/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: ECL mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
    26 |

    ECL mode

    27 |
    45 | 48 | 49 |

    Based on CodeMirror's clike mode. For more information see HPCC Systems web site.

    50 |

    MIME types defined: text/x-ecl.

    51 | 52 |
    53 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/http/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: HTTP mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
    26 |

    HTTP mode

    27 | 28 | 29 |
    39 | 40 | 43 | 44 |

    MIME types defined: message/http.

    45 |
    46 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/ntriples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: NTriples mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 28 | 29 |
    30 |

    NTriples mode

    31 |
    32 | 39 |
    40 | 41 | 44 |

    MIME types defined: text/n-triples.

    45 |
    46 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/ruby/test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({indentUnit: 2}, "ruby"); 6 | function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } 7 | 8 | MT("divide_equal_operator", 9 | "[variable bar] [operator /=] [variable foo]"); 10 | 11 | MT("divide_equal_operator_no_spacing", 12 | "[variable foo][operator /=][number 42]"); 13 | 14 | })(); 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/rust/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: Rust mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
    26 |

    Rust mode

    27 | 28 | 29 |
    52 | 53 | 58 | 59 |

    MIME types defined: text/x-rustsrc.

    60 |
    61 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/solr/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: Solr mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 20 | 33 | 34 |
    35 |

    Solr mode

    36 | 37 |
    38 | 47 |
    48 | 49 | 55 | 56 |

    MIME types defined: text/x-solr.

    57 |
    58 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/spreadsheet/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: Spreadsheet mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 25 | 26 |
    27 |

    Spreadsheet mode

    28 |
    29 | 30 | 37 | 38 |

    MIME types defined: text/x-spreadsheet.

    39 | 40 |

    The Spreadsheet Mode

    41 |

    Created by Robert Plummer

    42 |
    43 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/tiddlywiki/tiddlywiki.css: -------------------------------------------------------------------------------- 1 | span.cm-underlined { 2 | text-decoration: underline; 3 | } 4 | span.cm-strikethrough { 5 | text-decoration: line-through; 6 | } 7 | span.cm-brace { 8 | color: #170; 9 | font-weight: bold; 10 | } 11 | span.cm-table { 12 | color: blue; 13 | font-weight: bold; 14 | } 15 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/tiki/tiki.css: -------------------------------------------------------------------------------- 1 | .cm-tw-syntaxerror { 2 | color: #FFF; 3 | background-color: #900; 4 | } 5 | 6 | .cm-tw-deleted { 7 | text-decoration: line-through; 8 | } 9 | 10 | .cm-tw-header5 { 11 | font-weight: bold; 12 | } 13 | .cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/ 14 | padding-left: 10px; 15 | } 16 | 17 | .cm-tw-box { 18 | border-top-width: 0px ! important; 19 | border-style: solid; 20 | border-width: 1px; 21 | border-color: inherit; 22 | } 23 | 24 | .cm-tw-underline { 25 | text-decoration: underline; 26 | } -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/turtle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: Turtle mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
    26 |

    Turtle mode

    27 |
    41 | 47 | 48 |

    MIME types defined: text/turtle.

    49 | 50 |
    51 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/mode/z80/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeMirror: Z80 assembly mode 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 |
    26 |

    Z80 assembly mode

    27 | 28 | 29 |
    44 | 45 | 50 | 51 |

    MIME type defined: text/x-z80.

    52 |
    53 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror", 3 | "version":"5.0.0", 4 | "main": "lib/codemirror.js", 5 | "description": "In-browser code editing made bearable", 6 | "licenses": [{"type": "MIT", 7 | "url": "http://codemirror.net/LICENSE"}], 8 | "directories": {"lib": "./lib"}, 9 | "scripts": {"test": "node ./test/run.js"}, 10 | "devDependencies": {"node-static": "0.6.0", 11 | "phantomjs": "1.9.2-5", 12 | "blint": ">=0.1.1"}, 13 | "bugs": "http://github.com/codemirror/CodeMirror/issues", 14 | "keywords": ["JavaScript", "CodeMirror", "Editor"], 15 | "homepage": "http://codemirror.net", 16 | "maintainers":[{"name": "Marijn Haverbeke", 17 | "email": "marijnh@gmail.com", 18 | "web": "http://marijnhaverbeke.nl"}], 19 | "repository": {"type": "git", 20 | "url": "https://github.com/codemirror/CodeMirror.git"} 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/ambiance-mobile.css: -------------------------------------------------------------------------------- 1 | .cm-s-ambiance.CodeMirror { 2 | -webkit-box-shadow: none; 3 | -moz-box-shadow: none; 4 | box-shadow: none; 5 | } 6 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/cobalt.css: -------------------------------------------------------------------------------- 1 | .cm-s-cobalt.CodeMirror { background: #002240; color: white; } 2 | .cm-s-cobalt div.CodeMirror-selected { background: #b36539 !important; } 3 | .cm-s-cobalt.CodeMirror ::selection { background: rgba(179, 101, 57, .99); } 4 | .cm-s-cobalt.CodeMirror ::-moz-selection { background: rgba(179, 101, 57, .99); } 5 | .cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } 6 | .cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; } 7 | .cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 8 | .cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; } 9 | .cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; } 10 | 11 | .cm-s-cobalt span.cm-comment { color: #08f; } 12 | .cm-s-cobalt span.cm-atom { color: #845dc4; } 13 | .cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; } 14 | .cm-s-cobalt span.cm-keyword { color: #ffee80; } 15 | .cm-s-cobalt span.cm-string { color: #3ad900; } 16 | .cm-s-cobalt span.cm-meta { color: #ff9d00; } 17 | .cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; } 18 | .cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; } 19 | .cm-s-cobalt span.cm-bracket { color: #d8d8d8; } 20 | .cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; } 21 | .cm-s-cobalt span.cm-link { color: #845dc4; } 22 | .cm-s-cobalt span.cm-error { color: #9d1e15; } 23 | 24 | .cm-s-cobalt .CodeMirror-activeline-background {background: #002D57 !important;} 25 | .cm-s-cobalt .CodeMirror-matchingbracket {outline:1px solid grey;color:white !important} 26 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/eclipse.css: -------------------------------------------------------------------------------- 1 | .cm-s-eclipse span.cm-meta {color: #FF1717;} 2 | .cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; } 3 | .cm-s-eclipse span.cm-atom {color: #219;} 4 | .cm-s-eclipse span.cm-number {color: #164;} 5 | .cm-s-eclipse span.cm-def {color: #00f;} 6 | .cm-s-eclipse span.cm-variable {color: black;} 7 | .cm-s-eclipse span.cm-variable-2 {color: #0000C0;} 8 | .cm-s-eclipse span.cm-variable-3 {color: #0000C0;} 9 | .cm-s-eclipse span.cm-property {color: black;} 10 | .cm-s-eclipse span.cm-operator {color: black;} 11 | .cm-s-eclipse span.cm-comment {color: #3F7F5F;} 12 | .cm-s-eclipse span.cm-string {color: #2A00FF;} 13 | .cm-s-eclipse span.cm-string-2 {color: #f50;} 14 | .cm-s-eclipse span.cm-qualifier {color: #555;} 15 | .cm-s-eclipse span.cm-builtin {color: #30a;} 16 | .cm-s-eclipse span.cm-bracket {color: #cc7;} 17 | .cm-s-eclipse span.cm-tag {color: #170;} 18 | .cm-s-eclipse span.cm-attribute {color: #00c;} 19 | .cm-s-eclipse span.cm-link {color: #219;} 20 | .cm-s-eclipse span.cm-error {color: #f00;} 21 | 22 | .cm-s-eclipse .CodeMirror-activeline-background {background: #e8f2ff !important;} 23 | .cm-s-eclipse .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} 24 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/elegant.css: -------------------------------------------------------------------------------- 1 | .cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;} 2 | .cm-s-elegant span.cm-comment {color: #262; font-style: italic; line-height: 1em;} 3 | .cm-s-elegant span.cm-meta {color: #555; font-style: italic; line-height: 1em;} 4 | .cm-s-elegant span.cm-variable {color: black;} 5 | .cm-s-elegant span.cm-variable-2 {color: #b11;} 6 | .cm-s-elegant span.cm-qualifier {color: #555;} 7 | .cm-s-elegant span.cm-keyword {color: #730;} 8 | .cm-s-elegant span.cm-builtin {color: #30a;} 9 | .cm-s-elegant span.cm-link {color: #762;} 10 | .cm-s-elegant span.cm-error {background-color: #fdd;} 11 | 12 | .cm-s-elegant .CodeMirror-activeline-background {background: #e8f2ff !important;} 13 | .cm-s-elegant .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} 14 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/monokai.css: -------------------------------------------------------------------------------- 1 | /* Based on Sublime Text's Monokai theme */ 2 | 3 | .cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2;} 4 | .cm-s-monokai div.CodeMirror-selected {background: #49483E !important;} 5 | .cm-s-monokai.CodeMirror ::selection { background: rgba(73, 72, 62, .99); } 6 | .cm-s-monokai.CodeMirror ::-moz-selection { background: rgba(73, 72, 62, .99); } 7 | .cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;} 8 | .cm-s-monokai .CodeMirror-guttermarker { color: white; } 9 | .cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 10 | .cm-s-monokai .CodeMirror-linenumber {color: #d0d0d0;} 11 | .cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;} 12 | 13 | .cm-s-monokai span.cm-comment {color: #75715e;} 14 | .cm-s-monokai span.cm-atom {color: #ae81ff;} 15 | .cm-s-monokai span.cm-number {color: #ae81ff;} 16 | 17 | .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;} 18 | .cm-s-monokai span.cm-keyword {color: #f92672;} 19 | .cm-s-monokai span.cm-string {color: #e6db74;} 20 | 21 | .cm-s-monokai span.cm-variable {color: #a6e22e;} 22 | .cm-s-monokai span.cm-variable-2 {color: #9effff;} 23 | .cm-s-monokai span.cm-def {color: #fd971f;} 24 | .cm-s-monokai span.cm-bracket {color: #f8f8f2;} 25 | .cm-s-monokai span.cm-tag {color: #f92672;} 26 | .cm-s-monokai span.cm-link {color: #ae81ff;} 27 | .cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;} 28 | 29 | .cm-s-monokai .CodeMirror-activeline-background {background: #373831 !important;} 30 | .cm-s-monokai .CodeMirror-matchingbracket { 31 | text-decoration: underline; 32 | color: white !important; 33 | } 34 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/neat.css: -------------------------------------------------------------------------------- 1 | .cm-s-neat span.cm-comment { color: #a86; } 2 | .cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; } 3 | .cm-s-neat span.cm-string { color: #a22; } 4 | .cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; } 5 | .cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; } 6 | .cm-s-neat span.cm-variable { color: black; } 7 | .cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; } 8 | .cm-s-neat span.cm-meta {color: #555;} 9 | .cm-s-neat span.cm-link { color: #3a3; } 10 | 11 | .cm-s-neat .CodeMirror-activeline-background {background: #e8f2ff !important;} 12 | .cm-s-neat .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} 13 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/neo.css: -------------------------------------------------------------------------------- 1 | /* neo theme for codemirror */ 2 | 3 | /* Color scheme */ 4 | 5 | .cm-s-neo.CodeMirror { 6 | background-color:#ffffff; 7 | color:#2e383c; 8 | line-height:1.4375; 9 | } 10 | .cm-s-neo .cm-comment {color:#75787b} 11 | .cm-s-neo .cm-keyword, .cm-s-neo .cm-property {color:#1d75b3} 12 | .cm-s-neo .cm-atom,.cm-s-neo .cm-number {color:#75438a} 13 | .cm-s-neo .cm-node,.cm-s-neo .cm-tag {color:#9c3328} 14 | .cm-s-neo .cm-string {color:#b35e14} 15 | .cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier {color:#047d65} 16 | 17 | 18 | /* Editor styling */ 19 | 20 | .cm-s-neo pre { 21 | padding:0; 22 | } 23 | 24 | .cm-s-neo .CodeMirror-gutters { 25 | border:none; 26 | border-right:10px solid transparent; 27 | background-color:transparent; 28 | } 29 | 30 | .cm-s-neo .CodeMirror-linenumber { 31 | padding:0; 32 | color:#e0e2e5; 33 | } 34 | 35 | .cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; } 36 | .cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; } 37 | 38 | .cm-s-neo div.CodeMirror-cursor { 39 | width: auto; 40 | border: 0; 41 | background: rgba(155,157,162,0.37); 42 | z-index: 1; 43 | } 44 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/night.css: -------------------------------------------------------------------------------- 1 | /* Loosely based on the Midnight Textmate theme */ 2 | 3 | .cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; } 4 | .cm-s-night div.CodeMirror-selected { background: #447 !important; } 5 | .cm-s-night.CodeMirror ::selection { background: rgba(68, 68, 119, .99); } 6 | .cm-s-night.CodeMirror ::-moz-selection { background: rgba(68, 68, 119, .99); } 7 | .cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } 8 | .cm-s-night .CodeMirror-guttermarker { color: white; } 9 | .cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; } 10 | .cm-s-night .CodeMirror-linenumber { color: #f8f8f8; } 11 | .cm-s-night .CodeMirror-cursor { border-left: 1px solid white !important; } 12 | 13 | .cm-s-night span.cm-comment { color: #6900a1; } 14 | .cm-s-night span.cm-atom { color: #845dc4; } 15 | .cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; } 16 | .cm-s-night span.cm-keyword { color: #599eff; } 17 | .cm-s-night span.cm-string { color: #37f14a; } 18 | .cm-s-night span.cm-meta { color: #7678e2; } 19 | .cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; } 20 | .cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; } 21 | .cm-s-night span.cm-bracket { color: #8da6ce; } 22 | .cm-s-night span.cm-comment { color: #6900a1; } 23 | .cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; } 24 | .cm-s-night span.cm-link { color: #845dc4; } 25 | .cm-s-night span.cm-error { color: #9d1e15; } 26 | 27 | .cm-s-night .CodeMirror-activeline-background {background: #1C005A !important;} 28 | .cm-s-night .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;} 29 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/codemirror/theme/rubyblue.css: -------------------------------------------------------------------------------- 1 | .cm-s-rubyblue.CodeMirror { background: #112435; color: white; } 2 | .cm-s-rubyblue div.CodeMirror-selected { background: #38566F !important; } 3 | .cm-s-rubyblue.CodeMirror ::selection { background: rgba(56, 86, 111, 0.99); } 4 | .cm-s-rubyblue.CodeMirror ::-moz-selection { background: rgba(56, 86, 111, 0.99); } 5 | .cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; } 6 | .cm-s-rubyblue .CodeMirror-guttermarker { color: white; } 7 | .cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; } 8 | .cm-s-rubyblue .CodeMirror-linenumber { color: white; } 9 | .cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white !important; } 10 | 11 | .cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; } 12 | .cm-s-rubyblue span.cm-atom { color: #F4C20B; } 13 | .cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; } 14 | .cm-s-rubyblue span.cm-keyword { color: #F0F; } 15 | .cm-s-rubyblue span.cm-string { color: #F08047; } 16 | .cm-s-rubyblue span.cm-meta { color: #F0F; } 17 | .cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; } 18 | .cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def { color: white; } 19 | .cm-s-rubyblue span.cm-bracket { color: #F0F; } 20 | .cm-s-rubyblue span.cm-link { color: #F4C20B; } 21 | .cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; } 22 | .cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; } 23 | .cm-s-rubyblue span.cm-error { color: #AF2018; } 24 | 25 | .cm-s-rubyblue .CodeMirror-activeline-background {background: #173047 !important;} 26 | -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/lib/editor.md/lib/jquery.flowchart.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery.flowchart.js v1.1.0 | jquery.flowchart.min.js | jQuery plugin for flowchart.js. | MIT License | By: Pandao | https://github.com/pandao/jquery.flowchart.js | 2015-03-09 */ 2 | (function(factory){if(typeof require==="function"&&typeof exports==="object"&&typeof module==="object"){module.exports=factory}else{if(typeof define==="function"){factory(jQuery,flowchart)}else{factory($,flowchart)}}}(function(jQuery,flowchart){(function($){$.fn.flowChart=function(options){options=options||{};var defaults={"x":0,"y":0,"line-width":2,"line-length":50,"text-margin":10,"font-size":14,"font-color":"black","line-color":"black","element-color":"black","fill":"white","yes-text":"yes","no-text":"no","arrow-end":"block","symbols":{"start":{"font-color":"black","element-color":"black","fill":"white"},"end":{"class":"end-element"}},"flowstate":{"past":{"fill":"#CCCCCC","font-size":12},"current":{"fill":"black","font-color":"white","font-weight":"bold"},"future":{"fill":"white"},"request":{"fill":"blue"},"invalid":{"fill":"#444444"},"approved":{"fill":"#58C4A3","font-size":12,"yes-text":"APPROVED","no-text":"n/a"},"rejected":{"fill":"#C45879","font-size":12,"yes-text":"n/a","no-text":"REJECTED"}}};return this.each(function(){var $this=$(this);var diagram=flowchart.parse($this.text());var settings=$.extend(true,defaults,options);$this.html("");diagram.drawSVG(this,settings)})}})(jQuery)})); -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/scripts/tinymce.plugins/imageupload/plugin.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add('imageUpload', function (editor, url) { 2 | editor.addCommand('imageUploadDialog', function () { 3 | editor.windowManager.open({ 4 | title: 'Upload an image', 5 | file: '/scripts/tinymce.plugins/imageupload/dialog.html', 6 | width: 350, 7 | height: 135, 8 | buttons: [{ 9 | text: 'Upload', 10 | classes: 'widget btn primary first abs-layout-item', 11 | disabled: true, 12 | onclick: 'close' 13 | }, 14 | { 15 | text: 'Close', 16 | onclick: 'close' 17 | }] 18 | }); 19 | }); 20 | 21 | // Add a button that opens a window 22 | editor.addButton('imageUpload', { 23 | tooltip: 'Upload an image', 24 | icon: 'image', 25 | text: 'Upload', 26 | cmd: 'imageUploadDialog' 27 | }); 28 | }); -------------------------------------------------------------------------------- /src/DotNetBlog.Web/wwwroot/themes/default/styles/account.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #d2d6de; 3 | } 4 | 5 | .login-logo, 6 | .register-logo { 7 | font-size: 35px; 8 | text-align: center; 9 | margin-bottom: 25px; 10 | font-weight: 300; 11 | } 12 | 13 | .login-logo a, 14 | .register-logo a { 15 | color: #444; 16 | } 17 | 18 | .login-page, 19 | .register-page { 20 | background: #d2d6de; 21 | } 22 | 23 | .login-box, 24 | .register-box { 25 | width: 360px; 26 | margin: 7% auto; 27 | } 28 | 29 | @media (max-width: 768px) { 30 | .login-box, 31 | .register-box { 32 | width: 90%; 33 | margin-top: 20px; 34 | } 35 | } 36 | 37 | .login-box-body, 38 | .register-box-body { 39 | background: #fff; 40 | padding: 20px; 41 | border-top: 0; 42 | color: #666; 43 | } 44 | 45 | .login-box-body .form-control-feedback, 46 | .register-box-body .form-control-feedback { 47 | color: #777; 48 | } 49 | 50 | .login-box-msg, 51 | .register-box-msg { 52 | margin: 0; 53 | text-align: center; 54 | padding: 0 20px 20px 20px; 55 | } 56 | 57 | .social-auth-links { 58 | margin: 10px 0; 59 | } 60 | --------------------------------------------------------------------------------