From 61c1abccd836e0a03c44ac8b0fd6bab7e3c53b03 Mon Sep 17 00:00:00 2001 From: qwqcode <1149527164@qq.com> Date: Mon, 31 Dec 2018 22:33:22 +0800 Subject: [PATCH] Version 1.3.0.0! Update CefShap and Ui, fix some bugs. --- .gitmodules | 3 + .../cef_sharp => CefSharp}/.gitignore | 0 Nacollector/Browser/CrBrowser.cs | 35 +- Nacollector/Browser/CrDownloads.cs | 4 +- Nacollector/Browser/Handler/MenuHandler.cs | 16 +- .../Browser/Handler/ResourceSchemeHandler .cs | 62 + .../Handler/ResourceSchemeHandlerFactory.cs | 16 + Nacollector/ClassDiagram1.cd | 2 - Nacollector/JsActions/AppAction.cs | 6 + Nacollector/MainForm.cs | 9 +- Nacollector/Nacollector.csproj | 159 +- Nacollector/Program.cs | 28 +- Nacollector/Resources/html_res/app.html | 54 - Nacollector/Resources/html_res/assets/app.css | 1559 -------------- Nacollector/Resources/html_res/assets/app.js | 1800 ----------------- .../fonts/Material-Design-Iconic-Font.eot | Bin 42495 -> 0 bytes .../fonts/Material-Design-Iconic-Font.svg | 787 ------- .../fonts/Material-Design-Iconic-Font.ttf | Bin 99212 -> 0 bytes .../fonts/Material-Design-Iconic-Font.woff | Bin 50312 -> 0 bytes .../fonts/Material-Design-Iconic-Font.woff2 | Bin 38384 -> 0 bytes .../Resources/html_res/assets/icons/close.svg | 1 - .../html_res/assets/icons/maximize.svg | 1 - .../html_res/assets/icons/minimize.svg | 1 - .../html_res/assets/icons/unmaximize.svg | 1 - .../Resources/html_res/assets/jquery.min.js | 4 - .../Resources/html_res/assets/kunai_256px.png | Bin 6057 -> 0 bytes .../Resources/html_res/assets/logo.svg | 48 - .../material-design-iconic-font.min.css | 1 - .../Spiders/Business/CollItemDescImg.cs | 38 +- Nacollector/Ui/DraggableRegion.cs | 19 + Nacollector/Ui/FormBase.cs | 94 - Nacollector/Ui/SplashScreen.cs | 67 + NacollectorFrontend | 1 + 33 files changed, 279 insertions(+), 4537 deletions(-) create mode 100644 .gitmodules rename {Nacollector/Resources/cef_sharp => CefSharp}/.gitignore (100%) create mode 100644 Nacollector/Browser/Handler/ResourceSchemeHandler .cs create mode 100644 Nacollector/Browser/Handler/ResourceSchemeHandlerFactory.cs delete mode 100644 Nacollector/ClassDiagram1.cd delete mode 100644 Nacollector/Resources/html_res/app.html delete mode 100644 Nacollector/Resources/html_res/assets/app.css delete mode 100644 Nacollector/Resources/html_res/assets/app.js delete mode 100644 Nacollector/Resources/html_res/assets/fonts/Material-Design-Iconic-Font.eot delete mode 100644 Nacollector/Resources/html_res/assets/fonts/Material-Design-Iconic-Font.svg delete mode 100644 Nacollector/Resources/html_res/assets/fonts/Material-Design-Iconic-Font.ttf delete mode 100644 Nacollector/Resources/html_res/assets/fonts/Material-Design-Iconic-Font.woff delete mode 100644 Nacollector/Resources/html_res/assets/fonts/Material-Design-Iconic-Font.woff2 delete mode 100644 Nacollector/Resources/html_res/assets/icons/close.svg delete mode 100644 Nacollector/Resources/html_res/assets/icons/maximize.svg delete mode 100644 Nacollector/Resources/html_res/assets/icons/minimize.svg delete mode 100644 Nacollector/Resources/html_res/assets/icons/unmaximize.svg delete mode 100644 Nacollector/Resources/html_res/assets/jquery.min.js delete mode 100644 Nacollector/Resources/html_res/assets/kunai_256px.png delete mode 100644 Nacollector/Resources/html_res/assets/logo.svg delete mode 100644 Nacollector/Resources/html_res/assets/material-design-iconic-font.min.css create mode 100644 Nacollector/Ui/DraggableRegion.cs create mode 100644 Nacollector/Ui/SplashScreen.cs create mode 160000 NacollectorFrontend diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6b2d96e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "NacollectorFrontend"] + path = NacollectorFrontend + url = https://github.com/qwqcode/NacollectorFrontend diff --git a/Nacollector/Resources/cef_sharp/.gitignore b/CefSharp/.gitignore similarity index 100% rename from Nacollector/Resources/cef_sharp/.gitignore rename to CefSharp/.gitignore diff --git a/Nacollector/Browser/CrBrowser.cs b/Nacollector/Browser/CrBrowser.cs index 9ef5910..5f1cec5 100644 --- a/Nacollector/Browser/CrBrowser.cs +++ b/Nacollector/Browser/CrBrowser.cs @@ -26,15 +26,20 @@ public CrBrowser(MainForm form, string address) browser = new ChromiumWebBrowser(address); // BrowserSettings 必须在 Controls.Add 之前 - BrowserSettings browserSettings = new BrowserSettings(); - // browserSettings.WebSecurity = CefState.Disabled - browserSettings.FileAccessFromFileUrls = CefState.Enabled; // 必须 Enabled 不然 AJAX 请求 file:// 会显示 Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. - browserSettings.UniversalAccessFromFileUrls = CefState.Enabled; - browserSettings.DefaultEncoding = "UTF-8"; - browserSettings.BackgroundColor = (uint)ColorTranslator.FromHtml("#333333").ToArgb(); + BrowserSettings browserSettings = new BrowserSettings + { + // FileAccessFromFileUrls 必须 Enabled + // 不然 AJAX 请求 file:// 会显示 + // Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. + FileAccessFromFileUrls = CefState.Enabled, + UniversalAccessFromFileUrls = CefState.Enabled, + DefaultEncoding = "UTF-8", + BackgroundColor = (uint)ColorTranslator.FromHtml("#21252b").ToArgb() + }; + browserSettings.WebSecurity = CefState.Disabled; browser.BrowserSettings = browserSettings; - browser.MenuHandler = new MenuHandler(); + browser.MenuHandler = new MenuHandler(this); browser.LifeSpanHandler = new LifeSpanHandler(); browser.LoadHandler = new LoadHandler(); browser.DragHandler = new DragDropHandler(); @@ -42,7 +47,7 @@ public CrBrowser(MainForm form, string address) browser.FrameLoadEnd += new EventHandler(Browser_onFrameLoadEnd); browser.IsBrowserInitializedChanged += new EventHandler(Browser_onIsBrowserInitializedChanged); } - + // Frame 加载完毕时执行 private void Browser_onFrameLoadEnd(object sender, FrameLoadEndEventArgs e) { @@ -70,8 +75,11 @@ private void Browser_onIsBrowserInitializedChanged(object sender, IsBrowserIniti } else if (message.Msg == (int)WindowMessages.WM_LBUTTONDOWN) // 鼠标左键按下 { - NativeMethods.ReleaseCapture(); - form.SendHandleMessage(); // 执行 模拟标题栏拖动 + form.Invoke((MethodInvoker)delegate + { + NativeMethods.ReleaseCapture(); + NativeMethods.SendMessage(form.Handle, (int)WindowMessages.WM_NCLBUTTONDOWN, (int)HitTestValues.HTCAPTION, 0); // 执行 模拟标题栏拖动 + }); } else if (message.Msg == (int)WindowMessages.WM_RBUTTONDOWN) // 鼠标右键按下 { @@ -139,5 +147,12 @@ await task.ContinueWith(res => { } return result; } + + public void DownloadUrl(string url) + { + var cefBrowser = browser.GetBrowser(); + IBrowserHost ibwhost = cefBrowser == null ? null : cefBrowser.GetHost(); + ibwhost.StartDownload(url); + } } } \ No newline at end of file diff --git a/Nacollector/Browser/CrDownloads.cs b/Nacollector/Browser/CrDownloads.cs index 6ac6820..b5857dc 100644 --- a/Nacollector/Browser/CrDownloads.cs +++ b/Nacollector/Browser/CrDownloads.cs @@ -178,7 +178,7 @@ private void DownloadDo(string doType, ChromiumWebBrowser browser, EventArgs e) downloadUrl = downloadItem.OriginalUrl, totalBytes = downloadItem.TotalBytes, }); - browser.ExecuteScriptAsync($"downloads.addTask({callbackObj})"); + browser.ExecuteScriptAsync($"Downloads.addTask({callbackObj})"); } else if (doType == "update") { @@ -191,7 +191,7 @@ private void DownloadDo(string doType, ChromiumWebBrowser browser, EventArgs e) fullPath = downloadItem.FullPath, downloadUrl = downloadItem.Url }); - browser.ExecuteScriptAsync($"downloads.updateTask({callbackObj})"); + browser.ExecuteScriptAsync($"Downloads.updateTask({callbackObj})"); } } } diff --git a/Nacollector/Browser/Handler/MenuHandler.cs b/Nacollector/Browser/Handler/MenuHandler.cs index 49cb2ae..2ec9c84 100644 --- a/Nacollector/Browser/Handler/MenuHandler.cs +++ b/Nacollector/Browser/Handler/MenuHandler.cs @@ -11,10 +11,12 @@ namespace Nacollector.Browser.Handler { public class MenuHandler : IContextMenuHandler { + private CrBrowser crBrowser; private bool _showReload = false; - public MenuHandler(bool showReload = false) + public MenuHandler(CrBrowser crBrowser, bool showReload = false) { + this.crBrowser = crBrowser; _showReload = showReload; } @@ -24,7 +26,7 @@ public MenuHandler(bool showReload = false) private const int SaveLink = 26504; private const int CopyLink = 26505; private const int LinkOpenDefaultBrowser = 26506; - private const int LinkToZneiatProject = 26507; + private const int LinkToQWQCODEProject = 26507; private const int FeedbackProject = 26508; void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) @@ -80,7 +82,7 @@ void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowse if (_showReload) model.AddItem(CefMenuCommand.ReloadNoCache, "刷新 (ReloadNoCache)"); model.AddItem((CefMenuCommand)FeedbackProject, "反馈问题"); - model.AddItem((CefMenuCommand)LinkToZneiatProject, "开源项目"); + model.AddItem((CefMenuCommand)LinkToQWQCODEProject, "开源项目"); # if DEBUG model.AddItem((CefMenuCommand)ShowDevTools, "检查 (ShowDevTools)"); # endif @@ -114,11 +116,11 @@ bool IContextMenuHandler.OnContextMenuCommand(IWebBrowser browserControl, IBrows case LinkOpenDefaultBrowser: System.Diagnostics.Process.Start("explorer.exe", parameters.UnfilteredLinkUrl); break; - case LinkToZneiatProject: - System.Diagnostics.Process.Start("https://github.com/Zneiat/Nacollector"); + case LinkToQWQCODEProject: + System.Diagnostics.Process.Start("https://github.com/qwqcode/Nacollector"); break; case FeedbackProject: - System.Diagnostics.Process.Start("https://github.com/Zneiat/Nacollector/issues"); + System.Diagnostics.Process.Start("https://github.com/qwqcode/Nacollector/issues"); break; } @@ -132,7 +134,7 @@ bool IContextMenuHandler.OnContextMenuCommand(IWebBrowser browserControl, IBrows /// void ExecuteSaveFileByUrl(string url, IFrame frame) { - frame.ExecuteJavaScriptAsync("var a = document.createElement('a');a.setAttribute('href', \"" + url + "\");a.setAttribute('download','');a.click();"); + crBrowser.DownloadUrl(url); } void IContextMenuHandler.OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame) diff --git a/Nacollector/Browser/Handler/ResourceSchemeHandler .cs b/Nacollector/Browser/Handler/ResourceSchemeHandler .cs new file mode 100644 index 0000000..40e08da --- /dev/null +++ b/Nacollector/Browser/Handler/ResourceSchemeHandler .cs @@ -0,0 +1,62 @@ +using CefSharp; +using System; +using System.IO; +using System.Net; +using System.Reflection; +using System.Threading.Tasks; + +public class ResourceSchemeHandler : ResourceHandler +{ + public override bool ProcessRequestAsync(IRequest request, ICallback callback) + { + Uri u = new Uri(request.Url); + String file = u.Authority + u.AbsolutePath; + + Assembly ass = Assembly.GetExecutingAssembly(); + String resourcePath = ass.GetName().Name + "." + file.Replace("/", "."); + + Task.Run(() => + { + using (callback) + { + if (ass.GetManifestResourceInfo(resourcePath) != null) + { + Stream stream = ass.GetManifestResourceStream(resourcePath); + string mimeType = "application/octet-stream"; + switch (Path.GetExtension(file)) + { + case ".html": + mimeType = "text/html"; + break; + case ".js": + mimeType = "text/javascript"; + break; + case ".png": + mimeType = "image/png"; + break; + case ".appcache": + case ".manifest": + mimeType = "text/cache-manifest"; + break; + } + + // Reset the stream position to 0 so the stream can be copied into the underlying unmanaged buffer + stream.Position = 0; + // Populate the response values - No longer need to implement GetResponseHeaders (unless you need to perform a redirect) + ResponseLength = stream.Length; + MimeType = mimeType; + StatusCode = (int)HttpStatusCode.OK; + Stream = stream; + + callback.Continue(); + } + else + { + callback.Cancel(); + } + } + }); + + return true; + } +} \ No newline at end of file diff --git a/Nacollector/Browser/Handler/ResourceSchemeHandlerFactory.cs b/Nacollector/Browser/Handler/ResourceSchemeHandlerFactory.cs new file mode 100644 index 0000000..2782cb3 --- /dev/null +++ b/Nacollector/Browser/Handler/ResourceSchemeHandlerFactory.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CefSharp; + +class ResourceSchemeHandlerFactory : ISchemeHandlerFactory +{ + public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request) + { + return new ResourceSchemeHandler(); + } + + public static string SchemeName { get { return "resource"; } } +} diff --git a/Nacollector/ClassDiagram1.cd b/Nacollector/ClassDiagram1.cd deleted file mode 100644 index 7b89419..0000000 --- a/Nacollector/ClassDiagram1.cd +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Nacollector/JsActions/AppAction.cs b/Nacollector/JsActions/AppAction.cs index 5070094..8fa7c12 100644 --- a/Nacollector/JsActions/AppAction.cs +++ b/Nacollector/JsActions/AppAction.cs @@ -79,6 +79,12 @@ public void logFileClear() Logging.Clear(); } + // 调用浏览器下载文件 + public void downloadUrl(string url) + { + crBrowser.DownloadUrl(url); + } + // 升级操作 public void appUpdateAction(string srcUrl, string updateType) { diff --git a/Nacollector/MainForm.cs b/Nacollector/MainForm.cs index 3167e73..b0732e6 100644 --- a/Nacollector/MainForm.cs +++ b/Nacollector/MainForm.cs @@ -42,12 +42,15 @@ public MainForm() private void InitBrowser() { // 初始化内置浏览器 - string htmlPath = Utils.GetHtmlResPath("app.html"); +#if !DEBUG + string htmlPath = Utils.GetHtmlResPath("index.html"); if (string.IsNullOrEmpty(htmlPath)) { Application.Exit(); // 退出程序 } - +#else + string htmlPath = "http://127.0.0.1:8080"; +#endif crBrowser = new CrBrowser(this, htmlPath); // Need Update: https://github.com/cefsharp/CefSharp/issues/2246 @@ -125,7 +128,7 @@ private void MainForm_FormClosing(object sender, FormClosingEventArgs e) string dialogTxt = "确定退出 Nacollector?"; // 下载任务数统计 - int downloadingTaskNum = Convert.ToInt32(crBrowser.EvaluateScript("downloads.countDownloadingTask();", 0, TimeSpan.FromSeconds(3)).GetAwaiter().GetResult()); + int downloadingTaskNum = Convert.ToInt32(crBrowser.EvaluateScript("Downloads.countDownloadingTask();", 0, TimeSpan.FromSeconds(3)).GetAwaiter().GetResult()); if (downloadingTaskNum > 0) dialogTxt = $"有 {downloadingTaskNum} 个下载任务仍在继续!确定结束下载并关闭程序?"; diff --git a/Nacollector/Nacollector.csproj b/Nacollector/Nacollector.csproj index 0ee2bf3..c22d022 100644 --- a/Nacollector/Nacollector.csproj +++ b/Nacollector/Nacollector.csproj @@ -112,6 +112,11 @@ + + + + Form + Form @@ -125,6 +130,9 @@ MainForm.cs + + Form + @@ -151,138 +159,13 @@ LICENSE PreserveNewest - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always + + Resources\html_res\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + Resources\cef_sharp\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest @@ -304,18 +187,6 @@ Settings.settings True - - Always - - - Always - - - Always - - - Always - diff --git a/Nacollector/Program.cs b/Nacollector/Program.cs index 18a5ad2..347b053 100644 --- a/Nacollector/Program.cs +++ b/Nacollector/Program.cs @@ -109,17 +109,23 @@ private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEven private static void InitCef() { Cef.EnableHighDPISupport(); - var setting = new CefSettings(); - setting.Locale = "zh-CN"; - setting.AcceptLanguageList = "zh-CN,zh"; - setting.LogFile = Utils.GetTempPath("cef.log"); - setting.CachePath = Utils.GetTempPath("cef_cache"); - setting.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\CefSharp.BrowserSubprocess.exe"); - setting.LocalesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\locales\"); - setting.ResourcesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\"); - setting.RemoteDebuggingPort = 51228; - Cef.Initialize(setting, true, null); - // Cef.AddCrossOriginWhitelistEntry("https://", "http", "", true); + var settings = new CefSettings(); + settings.CefCommandLineArgs.Add("--allow-file-access-from-files", ""); + settings.CefCommandLineArgs.Add("--disable-web-security", ""); + settings.Locale = "zh-CN"; + settings.AcceptLanguageList = "zh-CN,zh"; + settings.LogFile = Utils.GetTempPath("cef.log"); + settings.CachePath = Utils.GetTempPath("cef_cache"); + settings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\CefSharp.BrowserSubprocess.exe"); + settings.LocalesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\locales\"); + settings.ResourcesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\cef_sharp\"); + settings.RemoteDebuggingPort = 51228; + /*settings.RegisterScheme(new CefCustomScheme() + { + SchemeName = ResourceSchemeHandlerFactory.SchemeName, + SchemeHandlerFactory = new ResourceSchemeHandlerFactory() + });*/ + Cef.Initialize(settings, true, null); } private static int exited = 0; diff --git a/Nacollector/Resources/html_res/app.html b/Nacollector/Resources/html_res/app.html deleted file mode 100644 index 1ac857c..0000000 --- a/Nacollector/Resources/html_res/app.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - Nacollector - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
-
- -
- - \ No newline at end of file diff --git a/Nacollector/Resources/html_res/assets/app.css b/Nacollector/Resources/html_res/assets/app.css deleted file mode 100644 index 8109305..0000000 --- a/Nacollector/Resources/html_res/assets/app.css +++ /dev/null @@ -1,1559 +0,0 @@ -html,body { - overflow: hidden; - margin: 0; - font-family: "Microsoft YaHei", "Helvitica Neue", Helvitica, Arial, "Hiragino Sans GB", "SimHei", sans-serif; - background: #333333; - font-size: 14px; - line-height: 1.42857143; - color: rgba(0, 0, 0, 0.6); - height: 100%; - transition: opacity .2s ease-in-out, background .2s ease-in-out; -} - -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box -} - -a { - transition: all .2s ease-in-out; -} - -:after,:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box -} - -button, input, select, textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -.wrap { - position: fixed; - top: 65px; - left: 0; - right: 0; - overflow-x: hidden; - overflow-y: auto; - height: calc(100vh - 75px); - width: 100vw; - opacity: 0; - transition: opacity .4s cubic-bezier(0.65, 0.05, 0.36, 1), background .4s cubic-bezier(0.65, 0.05, 0.36, 1); - background: #333333; -} - -.container { - overflow: hidden; - padding-right: 15px; - padding-left: 15px; - padding-top: 35px; - padding-bottom: 35px; - margin-right: auto; - margin-left: auto; -} - -@media (min-width: 768px) { - .container { - width:750px - } -} - -@media (min-width: 992px) { - .container { - width:970px - } -} - -@media (min-width: 1150px) { - .container { - width:1100px - } -} - -@media (min-width: 1200px) { - .container { - width:1170px - } -} - -::-webkit-scrollbar { - width: 4px; - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: rgba(86, 86, 86, 0.3); -} - -::-webkit-scrollbar-thumb:window-inactive { - background: rgba(86, 86, 86, 0.3); -} - -::-webkit-scrollbar-thumb:vertical:hover { - background: rgba(65, 74, 82, 0.77); -} - -::-webkit-scrollbar-thumb:vertical:active { - background: rgba(41, 47, 53, 0.77); -} - -.wrap::-webkit-scrollbar-thumb, .task-runtime::-webkit-scrollbar { - width: 4px; - background: transparent; -} - -.wrap::-webkit-scrollbar-thumb, .task-runtime::-webkit-scrollbar-thumb { - background: rgba(191, 191, 191, 0.57); -} - -.wrap::-webkit-scrollbar-thumb:window-inactive, .task-runtime::-webkit-scrollbar-thumb:window-inactive { - background: rgba(191, 191, 191, 0.57); -} - -.wrap::-webkit-scrollbar-thumb:vertical:hover, .task-runtime::-webkit-scrollbar-thumb:vertical:hover { - background: rgba(220, 220, 220, 0.77); -} - -.wrap::-webkit-scrollbar-thumb:vertical:active, .task-runtime::-webkit-scrollbar-thumb:vertical:active { - background: rgba(255, 255, 255, 0.77); -} - -::-webkit-input-placeholder { - color: #97a4ab; -} - -.row { - margin-left: -15px; - margin-right: -15px; -} - -.layui-layer-in { -} - -.anim-fade-in { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; - -webkit-animation-duration: .3s; - animation-duration: .3s; -} - -.anim-fade-out { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; - -webkit-animation-duration: .2s; - animation-duration: .2s; -} - -.anim-flash { - -webkit-animation-name: flash; - animation-name: flash -} - -@keyframes fadeIn { - 0% { - opacity: 0 - } - - to { - opacity: 1 - } -} - -@keyframes fadeOut { - 100% { - opacity: 0; - } - - 0% { - } -} - -@keyframes flash { - 0%,50%,to { - opacity: 1 - } - - 25%,75% { - opacity: 0 - } -} - -/* user-select disable */ -.title-bar, .top-nav-bar, .big-header, .app-select, .app-form label, ::-webkit-input-placeholder { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: default; -} - -/* Loading Indicator */ -.loading-indicator { - display: flex; - width: 100%; - height: 100%; - align-items: center; - justify-content: center; -} - -.loading-indicator .inner { - position: relative; - width: 50px; - height: 50px -} - -.loading-indicator svg { - animation: loading-indicator-rotate 2s linear infinite; - transform-origin: center center; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0 -} - -.loading-indicator svg circle { - stroke-dasharray: 1,200; - stroke-dashoffset: 0; - animation: loading-indicator-dash 1.5s ease-in-out infinite,loading-indicator-color 6s ease-in-out infinite; - stroke-linecap: round -} - -@keyframes loading-indicator-rotate { - 100% { - transform: rotate(360deg) - } -} - -@keyframes loading-indicator-dash { - 0% { - stroke-dasharray: 1,200; - stroke-dashoffset: 0 - } - - 50% { - stroke-dasharray: 89,200; - stroke-dashoffset: -35px - } - - 100% { - stroke-dasharray: 89,200; - stroke-dashoffset: -124px - } -} - -@keyframes loading-indicator-color { - 0%,100% { - stroke: #ff5652 - } - - 40% { - stroke: #2196F3 - } - - 66% { - stroke: #32c787 - } - - 80%,90% { - stroke: #ffc107 - } -} - -/* Title Bar */ -.title-bar { - position: fixed; - top: 0; - left: 0; - right: 0; - height: 25px; - width: 100vw; - background: #1565c0; - z-index: 99999; -} - -.title-bar.blur { - /* background: #1565c0; */ -} - -.title-bar-inner { - height: 100%; - width: 100%; - -webkit-app-region: drag; - user-select: none; - display: flex; - justify-content: center; - align-items: center; - position: relative; -} - -.title-bar .controls { - display: flex; - width: 120px; - height: 100%; - justify-content: space-between; - position: absolute; - right: 7px; -} - -.title-bar .controls .window-icon-bg { - display: inline-block; - -webkit-app-region: no-drag; - height: 100%; - width: 33.34%; - transition: background .2s ease-in-out; -} - -.title-bar .controls .window-icon { - height: 100%; - width: 100%; - -webkit-mask-size: 23.1%; - background-color: #ffffff; -} - -.title-bar .controls .window-minimize { - -webkit-mask: url(./icons/minimize.svg) no-repeat 50% 50%; -} - -.title-bar .controls .window-maximize { - -webkit-mask: url(./icons/maximize.svg) no-repeat 50% 50%; -} - -.title-bar .controls .window-unmaximize { - -webkit-mask: url(./icons/unmaximize.svg) no-repeat 50% 50%; -} - -.title-bar .controls .window-close { - -webkit-mask: url(./icons/close.svg) no-repeat 50% 50%; -} - -.title-bar .controls .window-icon-bg:hover { - background-color: hsla(0,0%,100%,.1); -} - -.title-bar .controls .window-icon-bg.red:hover { - background-color: rgba(232,17,35,.9); -} - -/* Nav Bar */ -.top-nav-bar { - z-index: 999; - position: fixed; - height: 40px; - left: 0; - right: 0; - width: 100vw; - top: 25px; - background: #1565c0; - display: flex; - align-items: center; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - -webkit-app-region: drag; -} - -.top-nav-bar .left-items, .top-nav-bar .right-items { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - padding: 0 10px; -} - -.top-nav-bar .left-items { - float: left; -} - -.top-nav-bar .left-items .nav-title { - color: #FFF; - font-size: 14px; - padding: 0 10px; - transition: opacity .2s; -} - -.top-nav-bar .left-items .nav-title.changing { - opacity: 0; -} - -.top-nav-bar .right-items { - float: right; -} - -.top-nav-bar .right-items .nav-btns { - float: right; - overflow: hidden; - border-radius: 0; - -webkit-app-region: no-drag; -} - -.top-nav-bar .right-items .nav-btns .btn-group { - display: inline-block; - padding-right: 15px; - margin-right: 15px; - border-right: 1px solid rgba(255, 255, 255, 0.08); - -webkit-app-region: no-drag; -} - -.top-nav-bar .right-items .nav-btns .btn-group:last-child { - padding-right: 0; - margin-right: 0; - border: none; -} - -.top-nav-bar .right-items .nav-btns .btn-group > a { - position: relative; - font-size: 15px; - color: #FFF; - cursor: pointer; - padding: 3px 10px; - display: inline-block; - transition: background .2s ease-in-out; - border-radius: 2px; - margin-left: 5px; -} - -.top-nav-bar .right-items .nav-btns .btn-group > a.show-top-badge:before { - content: ''; - width: 7px; - height: 7px; - background-color: #ff605c; - color: #FFF; - border-radius: 50%; - position: absolute; - top: 4px; - right: 0; - left: 25px; - margin: auto; - -webkit-animation-name: flash; - animation-name: flash; - -webkit-animation-duration: 2s; - animation-duration: 2s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; - animation-iteration-count: infinite; -} - -.top-nav-bar .right-items .nav-btns .btn-group > a:first-child { - margin-left: 0; -} - -.top-nav-bar .right-items .nav-btns .btn-group > a > i { - width: 20px; - text-align: center; -} - -.top-nav-bar .right-items .nav-btns .btn-group > a:hover { - background: rgba(255,255,255,.2); -; } - -/* Taskgen */ -.taskgen-header { - display: block; - margin-bottom: 20px; - text-align: center; -} - -.taskgen-header .app-logo { - margin-bottom: 20px; - margin-top: 20px; - width: 340px; -} - -.taskgen-form-toggle, .taskgen-main { - position: relative; - min-height: 1px; - padding-left: 15px; - padding-right: 15px; -} - -@media (min-width: 992px) { - .taskgen-main { - width: 73.66666667%; - float: left; - } - - .taskgen-form-toggle { - width: 26.33333333%; - float: left; - } -} - -.taskgen-form-toggle .classname-btns { - background: rgb(47, 47, 47); - padding: 7px 0; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - border-radius: 2px; -} - -.taskgen-form-toggle .classname-btns a { - position: relative; - display: block; - cursor: pointer; - padding: 10px 20px; - margin-bottom: 10px; - -webkit-transition: all .2s ease-in-out; - transition: all .2s ease-in-out; - background: #2f2f2f; - color: #75838a; - text-align: center; - border-left: 2px solid transparent; -} - -.taskgen-form-toggle .classname-btns a:last-child { - margin-bottom: 0; -} - -.taskgen-form-toggle .classname-btns a:hover { - color: #2588f3; -} - -.taskgen-form-toggle .classname-btns a.active { - color: #2588f3; - border-left: 2px solid #2d4558; -} - -.taskgen-form-toggle .namespace-dropdown { - position: relative; - background: rgb(47, 47, 47); - padding: 0; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - border-radius: 2px; - font-size: 15px; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-selected { - display: block; - width: 100%; - background: transparent; - border: none; - outline: none; - text-align: center; - line-height: 40px; - color: #2588f3; - height: 40px; - cursor: pointer; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-selected:after { - font-family: 'Material-Design-Iconic-Font'; - content: '\f2f9'; - position: absolute; - top: 0; - right: 15px; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option { - display: none; - position: absolute; - z-index: 77; - top: 0; - padding: 0; - margin: 0; - list-style: none; - width: 100%; - background: #FFF; - border: 0; - border-radius: 2px; - box-shadow: 0 2px 10px rgba(0,0,0,.075); - color: #707070; - overflow: hidden; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option.show { - display: block; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option > li { - position: relative; - text-align: center; - height: 40px; - line-height: 40px; - cursor: pointer; - transition: all .2s ease-in-out; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option > li:hover { - background-color: #f7f7f9; - color: #1d1e1f; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option > li.selected { - background-color: #f7f7f9; - color: #1d1e1f; -} - -.taskgen-form-toggle .namespace-dropdown .dropdown-option > li.selected:before { - font-family: 'Material-Design-Iconic-Font'; - content: '\f26b'; - position: absolute; - top: 0; - right: 15px; - color: #1d1e1f; -} - -.taskgen-form-toggle div:not(:last-child) { - margin-bottom: 15px; -} - -.taskgen-main { - background: #2f2f2f; - padding: 0; -} - -.taskgen-form { - margin-left: auto; - margin-right: auto; - float: none; - padding: 30px; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - border-radius: 2px; -} - -.taskgen-form label { - display: inline-block; - margin-bottom: 8px; - color: #75838a; -} - -.taskgen-form .form-group { - margin-bottom: 18px; - position: relative; - overflow: hidden; -} - -.taskgen-form .form-control { - padding: 5px 17px; - width: 100%; - height: 34px; - border: 1px solid transparent; - font-size: 14px; - line-height: 1.42857143; - -webkit-transition: all .2s ease-in-out; - transition: all .2s ease-in-out; - color: #2588f3; - background: #32363c; - resize: none; -} - -.taskgen-form .form-control.has-error { - color: #EF5350; - background: rgb(80, 49, 49); -} - -.taskgen-form .form-control:focus { - outline: none; - border: 1px solid #4285f4; -} - -.taskgen-form textarea.form-control { - padding: 13px 17px; - height: 240px; - overflow-x: hidden; -} - -.taskgen-form .form-btns { - display: block; - overflow: hidden; - margin-top: 25px; -} - -.taskgen-form .submit-btn { - display: inline-block; - padding: 7px 50px; - border: none; - color: #3492de; - background: rgb(50, 54, 60); - outline: none; - font-size: 13.3333px; - cursor: pointer; - -webkit-transition: all .2s ease-in-out; - transition: all .2s ease-in-out; - font-size: 14px; - font-weight: 400; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; -} - -.taskgen-form .submit-btn:hover, .taskgen-form .submit-btn:active { - color: #2fc798; -} - -/* Task Runtime */ -.task-runtime { - position: absolute; - top: 0; - left: 0; - background: rgba(21, 29, 41, 0.88); - height: 100%; - width: 100%; - overflow: hidden; - overflow-y: auto; -} - -.task-runtime .task-item { -} - -.task-runtime .task-item .task-log-table { -} - -.task-runtime .task-item .task-log-table .line { - animation: fadeIn .3s; - color: #cacaca; - word-break: break-all; - margin-bottom: 8px; - font-size: 16px; - white-space: pre-wrap; -} - -.task-runtime .task-item .task-log-table .line a { - text-decoration: none; - color: rgba(255, 255, 255, 0.9); -} - -.task-runtime .task-item .task-log-table .line a:hover {color: #ffffff;} - -.task-runtime .task-item .task-log-table [data-level="I"].line { - color: #38a5ff; -} - -.task-runtime .task-item .task-log-table [data-level="S"].line { - color: #32f388; -} - -.task-runtime .task-item .task-log-table [data-level="W"].line { - color: #ffc761; -} - -.task-runtime .task-item .task-log-table [data-level="E"].line { - color: #ff4545; -} - -.task-runtime .task-item .task-log-table .line > .tag { - margin-right: 7px; -} - -/* Navbar Panel */ -.navbar-panel { - position: absolute; - background: #FFF; - width: 400px; - height: 430px; - z-index: 999; - color: #757e91; - word-break: break-all; - overflow: hidden; - overflow-y: auto; - border-radius: 2px; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - display: none; -} - -.navbar-panel.show { - display: block; -} - -.navbar-panel .panel-header { -} - -.navbar-panel .panel-header .panel-title { - padding: 20px 25px; - text-align: center; - font-size: 16px; - /* border-bottom: 1px solid #efefef; */ - color: #2196f3; -} - -.navbar-panel .panel-header .panel-title > i { - margin-right: 5px; - vertical-align: middle; -} - -.navbar-panel .downloads-list { -} - -.navbar-panel .downloads-list .download-item { - position: relative; - border-top: 1px solid #efefef; -} - -.navbar-panel .downloads-list .download-item a { - cursor: pointer; -} - -.navbar-panel .downloads-list .download-item .details { - padding: 10px 10px; -} - -.navbar-panel .downloads-list .download-item .details .header { - margin-bottom: 10px; -} - -.navbar-panel .downloads-list .download-item .details .header .file-name { - color: #2196f3; - display: block; - font-size: 16px; - margin-bottom: 6px; -} - -.navbar-panel .downloads-list .download-item .details .header .file-name:hover { -} - -.navbar-panel .downloads-list .download-item .details .header .download-url { - display: block; - font-size: 12px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - color: rgba(27, 27, 27, 0.6); -} - -.navbar-panel .downloads-list .download-item .details .header .download-url:hover { -} - -.navbar-panel .downloads-list .download-item .details .description { - margin-top: 5px; - margin-bottom: 5px; - font-size: 12px; - color: #717171; -} - -.navbar-panel .downloads-list .download-item .details .progress { - background-color: #e2e2e2; - position: relative; - height: 2px; -} - -.navbar-panel .downloads-list .download-item .details .progress.indeterminate { - overflow: hidden; -} - -.navbar-panel .downloads-list .download-item .details .progress .progress-bar { - position: absolute; - width: 0; - max-width: 100%; - height: 100%; - text-align: right; - background-color: #2196f3; - transition: all .3s; - text-align: right; -} - -.navbar-panel .downloads-list .download-item .details .progress .progress-bar .progress-text { - position: relative; - top: -18px; - line-height: 18px; - font-size: 12px; - color: #666; - display: inline-block; - vertical-align: top; -} - -.navbar-panel .downloads-list .download-item .details .progress.indeterminate .progress-bar { - animation: progress-bar-indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; - transition: all 0.2s linear; - will-change: left, right; - width: 30% !important; -} - -@-webkit-keyframes progress-bar-indeterminate { - 0% { - left: -35%; - right: 100%; - } - - 60% { - left: 100%; - right: -90%; - } - - 100% { - left: 100%; - right: -90%; - } -} - -.navbar-panel .downloads-list .download-item .details .action-bar { - margin-top: 5px; -} - -.navbar-panel .downloads-list .download-item .details .action-bar a { - color: #2196f3; - margin-right: 10px; -} - -.navbar-panel .downloads-list .download-item .details .action-bar a:last-child { - margin-right: 0; -} - -.navbar-panel .downloads-list .download-item .details .action-bar a:hover { -} - -.navbar-panel .downloads-list .download-item .icon-wrapper { - position: absolute; - right: 0; - top: 0; -} - -.navbar-panel .downloads-list .download-item .icon-wrapper .remove-btn { - font-size: 16px; - line-height: 17px; - vertical-align: middle; - outline: none; - width: 30px; - height: 30px; - background: none; - margin: 0; - border: none; - padding: 0; - cursor: pointer; - color: #93adb9; -} - -.navbar-panel .downloads-list .download-item[dl-status="downloading"] { -} - -.navbar-panel .downloads-list .download-item[dl-status="pause"] { -} - -.navbar-panel .downloads-list .download-item[dl-status="pause"] .details .progress { -} - -.navbar-panel .downloads-list .download-item[dl-status="pause"] .details .progress .progress-bar { - background-color: #b7b7b7; -} - -.navbar-panel .downloads-list .download-item[dl-status="done"] { -} - -.navbar-panel .downloads-list .download-item[dl-status="done"] .details .progress { - display: none; -} - -.navbar-panel .downloads-list .download-item[dl-status="done"] .details .progress .progress-bar { -} - -.navbar-panel .downloads-list .download-item[dl-status="fail"] .details .progress .progress-bar { - background: #f95c57; -} - -.navbar-panel .downloads-list .download-item[dl-status="fail"] .details .progress.indeterminate .progress-bar { - width: 100% !important; - animation: none; -} - -.navbar-panel .downloads-list .download-item[dl-status="cancelled"] { -} - -.navbar-panel .downloads-list .download-item[dl-status="cancelled"] .details .header .file-name { - color: rgba(19, 19, 19, 0.6); - text-decoration: line-through; -} - -.navbar-panel .downloads-list .download-item[dl-status="cancelled"] .details .description { - display: none; -} - -.navbar-panel .downloads-list .download-item[dl-status="cancelled"] .details .progress { - display: none; -} - -/* Tooltip */ -.tooltip { - position: absolute; - z-index: 1070; - display: block; - font-family: inherit; - font-size: 12px; - font-style: normal; - font-weight: normal; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - white-space: normal; - filter: alpha(opacity=0); - opacity: 0; - line-break: auto; -} - -.tooltip.in { - filter: alpha(opacity=90); - opacity: .9; -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 2px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} - -.tooltip.top-left .tooltip-arrow { - right: 5px; - bottom: 0; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} - -.tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} - -.tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} - -.tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} - -/* Sidebar Layer */ -.sidebar-layer { - opacity: 0; - position: fixed; - z-index: 997; - height: 100%; - width: 100%; - top: 0px; - right: -100%; - background-color: rgba(0, 0, 0, 0.54); - transition: left 0ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, opacity 400ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; -} - -.sidebar-layer.show { - opacity: 1; - right: 0; -} - -.sidebar-layer .sidebar-block { - position: fixed; - z-index: 998; - width: 360px; - top: 65px; - height: calc(100vh - 65px); - right: 0px; - color: rgba(0, 0, 0, 0.87); - background: rgb(255, 255, 255); - transition: transform 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; - box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 10px, rgba(0, 0, 0, 0.23) 0px 3px 10px; - border-radius: 0px; - padding: 0; - transform: translate(370px, 0px); - /* 360px + 10px */ -} - -.sidebar-layer .sidebar-block.show { - transform: translate(0px, 0px) !important; -} - -.sidebar-layer .sidebar-block .sidebar-header { - background-color: rgb(33, 150, 243); - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - display: flex; - justify-content: space-between; - align-items: center; - height: 50px; - padding: 0 15px; -} - -.sidebar-layer .sidebar-block .sidebar-header > * { - display: flex; - font-size: 16px; - color: #FFF; -} - -.sidebar-layer .sidebar-block .sidebar-header .header-left { -} - -.sidebar-layer .sidebar-block .sidebar-header .header-right { -} - -.sidebar-layer .sidebar-block .sidebar-header .header-right i { -} - -.sidebar-layer .sidebar-block .sidebar-header .header-right button { - background: transparent; - border: none; - padding: 0; - margin: 0; - color: #FFF; - cursor: pointer; - width: 25px; - height: 25px; - outline: none; -} - -.sidebar-layer .sidebar-block .sidebar-inner { - overflow-x: hidden; - overflow-y: auto; - width: 100%; - height: 100%; - padding-bottom: 55px; -} - -.sidebar-layer .sidebar-block .task-manager { -} - -.sidebar-layer .sidebar-block .task-manager .task-item { - display: flex; - align-items: center; - border-bottom: 1px solid hsla(0,0%,78%,.3); - padding: 16px 0; - flex-direction: row; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .left { - float: left; - text-align: center; - display: flex; - align-items: center; - justify-content: center; - flex-grow: 1; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .left > i { - display: flex; - font-size: 24px; - color: #4265c7; - width: 40px; - height: 40px; - align-items: center; - justify-content: center; - background: transparent; - border-radius: 50%; - cursor: pointer; - transition: all 0.2s; - box-shadow: 0 1px 5px rgba(84, 84, 84, 0.2); -} - -.sidebar-layer .sidebar-block .task-manager .task-item:hover .left > i { - color: #FFF; - background: #4265c7; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right { - float: right; - width: 360px; - padding-right: 30px; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .task-title { - margin-top: 0; - margin-bottom: 5px; - font-weight: 500; - font-size: 18px; - color: #4265c7; - cursor: pointer; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .task-desc { - margin-bottom: 10px; - margin-top: 0; - font-size: 13px; - color: #737373; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar { -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar .action-btn { - margin-right: 10px; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar .action-btn { - color: #676e75; - margin-right: 6px; - cursor: pointer; - transition: all 0.2s; - font-size: 13px; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar .action-btn:hover { - color: #4265c7; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar .action-btn > i { - width: 12px; - text-align: center; -} - -.sidebar-layer .sidebar-block .task-manager .task-item .right .action-bar .action-btn:last-child { - margin-right: 0; -} - -/* Dialog Layer */ -.dialog-layer { - position: absolute; - display: flex; - z-index: 1000; - background-color: rgba(21, 101, 192, 0.11); - top: 0; - left: 0; - width: 100%; - height: 100%; - align-items: center; - justify-items: center; -} - -.dialog-layer .dialog-inner { - display: flex; - flex-direction: column; - width: 430px; - padding: 15px 0; - border-radius: 2px; - background-color: #fff; - box-shadow: 1px 1px 50px rgba(0,0,0,.3); - margin: 0 auto; -} - -.dialog-layer .dialog-title { - display: flex; - position: relative; - justify-content: space-between; - padding: 10px 30px 15px 30px; - border-bottom: 0 solid #f6f6f6; - font-size: 16px; - color: #333; -} - -.dialog-layer .dialog-title .right-btn { - width: 25px; - text-align: center; - cursor: pointer; -} - -.dialog-layer .dialog-title .right-btn:hover { - color: #03A9F4; -} - -.dialog-layer .dialog-title .right-btn > i { - line-height: 25px; -} - -.dialog-layer .dialog-content { - position: relative; - flex: 1 1 auto; - padding: 10px 30px 10px 30px; - font-size: 13px; - font-weight: 400; - line-height: 1.5; - color: #707070; - overflow-x: hidden; - overflow-y: auto; - max-height: 150px; - word-break: break-all; -} - -.dialog-layer .dialog-bottom { - display: flex; - padding: 15px 25px 0 25px; - -webkit-box-pack: end; - justify-content: flex-end; - -webkit-box-align: center; - align-items: center; - color: #575757; -} - -.dialog-layer .dialog-bottom .dialog-btn { - color: #2196f3; - font-weight: 500; - cursor: pointer; - border: 0; - text-align: center; - border-radius: 2px; - padding: 6px 13px; -} - -.dialog-layer .dialog-bottom .dialog-btn:hover { - background-color: #f6f6f6; -} - -.dialog-layer .dialog-bottom .dialog-btn:not(first-child) { - margin-left: 5px; -} - -/* Widgets */ -.widget-float-img { - position: absolute; - z-index: 1000; - width: 250px; - height: 250px; - overflow: hidden; - border-radius: 1px; - background: #efefef; - padding: 10px; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.49); - display: flex; - align-items: center; - justify-items: center; -} - -.widget-float-img > img { - height: auto; - width: auto; - margin: 0 auto; - max-height: 100%; - max-width: 100%; - border-radius: 2px; - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); -} - -.notify-layer { - position: absolute; - top: 20px; - left: 0px; - right: 0px; - margin: 0px auto; - max-width: 600px; - width: 100%; - padding-right: 60px; - z-index: 99999; -} - -.notify-layer .notify-item { - display: block; - overflow: hidden; - background-color: #2c2c2c; - border-color: #2c2c2c; - color: #FFF; - box-shadow: 0 0 5px rgba(0,0,0,.4); - border-radius: 2px; -} - -.notify-layer .notify-item:not(:last-child) { - margin-bottom: 15px; -} - -.notify-layer .notify-item.type-s { - background: #52a984; - color: #FFF; -} - -.notify-layer .notify-item.type-e { - color: #FFF; - background: #b14a45; -} - -.notify-layer .notify-item p { - padding: 10px 15px; - margin: 0; -} - -.sidebar-layer .sidebar-block .setting { -} - -.sidebar-layer .sidebar-block .setting .setting-group { -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-group-title { - color: #2196f3; - font-size: 13px; - font-weight: 500; - margin: 20px 0 5px; - line-height: 1; - padding: 0 20px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item { - display: flex; - align-items: center; - min-height: 56px; - padding: 0; - font-size: 15px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item:not(:last-child) { - border-bottom: 1px solid rgba(199, 199, 199, 0.3); -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block { - color: #212121; - width: 100%; - height: 56px; - border: 0; - background: transparent; - cursor: pointer; - transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; - outline: none; - padding: 0 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - text-align: left; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block:hover { - /*background: rgba(0, 0, 0, 0.03);*/ -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block:active { - /*background: rgba(0, 0, 0, 0.08);*/ -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .two-line { - overflow: hidden; - padding: 0 20px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .two-line .label { - display: block; - color: #212121; - margin-bottom: 1px; - font-size: 13px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .two-line .value { - display: block; - color: #757575; - font-size: 13px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .two-line .value a { - color: #757575; - text-decoration: none; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle { -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .left-text { - float: left; - position: relative; - display: block; - width: calc(100% - 46px); -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle { - float: left; - position: relative; - display: block; - width: 36px; - margin-right: 0px; - margin-left: 8px; - padding: 4px 0px 6px 2px; - transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle-bar { - transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; - width: 100%; - height: 14px; - border-radius: 30px; - background-color: #bdbdbd; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle-button { - background-color: rgb(245, 245, 245); - transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; - box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.12) 0px 1px 4px; - border-radius: 50%; - position: absolute; - top: 1px; - left: 0px; - width: 20px; - height: 20px; - line-height: 24px; -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle.turn-on {} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle.turn-on .toggle-bar { - background-color: rgba(33, 150, 243, 0.5); -} - -.sidebar-layer .sidebar-block .setting .setting-group .setting-item .setting-btn-block.setting-btn-toggle .toggle.turn-on .toggle-button { - background-color: rgb(33, 150, 243); - margin-left: 20px; -} \ No newline at end of file diff --git a/Nacollector/Resources/html_res/assets/app.js b/Nacollector/Resources/html_res/assets/app.js deleted file mode 100644 index fe5df29..0000000 --- a/Nacollector/Resources/html_res/assets/app.js +++ /dev/null @@ -1,1800 +0,0 @@ -/** - * Created by qwqcode on 2017/7/15. - * https://github.com/qwqcode/Nacollector - */ - -/** - * 页面初始化 - */ -$(document).ready(function () { - // 初始化 NavBar - AppNavbar.init(); - // 初始化 Tooltip - $('[data-toggle="tooltip"]').tooltip(); - // 浏览器初始化时白色闪光 减少违和感 - setTimeout(function () { - $(WRAP_SEL).css("opacity","1"); - }, 10); - // 任务生成器初始化 - TaskGen.init(); - // 任务管理器层初始化 - Task.taskManagerLayer.init(); - // 点击操作按钮列表第一个 - $(TaskGen.sel.formToggleBtns+' a:nth-child(1)').click(); - // 下载面板初始化 - downloads.init(); - // 设置初始化 - setting.init(); - // 设置程序当前版本号 - AppAction.getVersion().then(function (version) { - AppAction.version = version; - // 检测更新 - AppUpdate.check(true); - }); - // 开发者工具显示方式 - $(document).keydown(function (e) { - if (e.altKey && event.keyCode === 123) { - AppAction.showDevTools(); - } - }); -}); - -/** - * functions in .cs - * @type {{getVersion, _utilsReqIeProxy, logFileClear, appUpdateAction}} - */ -window.AppAction = AppAction || {}; -window.AppAction.utilsReqIeProxy = function (isEnable) { - if (isEnable === undefined) - isEnable = !!setting.get('UtilsReqIeProxy'); - - setting.set('UtilsReqIeProxy', isEnable); - AppAction._utilsReqIeProxy(isEnable); -}; - -/** - * Selectors - */ -const WRAP_SEL = '.wrap'; - -/** - * 导航栏 - */ -window.AppNavbar = { - sel: { - nav: '.top-nav-bar', - navTitle: '.top-nav-bar .nav-title' - }, - // 初始化 Navbar - init: function () { - $('
').appendTo(this.sel.nav); - // 导航栏操作按钮 - AppNavbar.btn.groupAdd('main-btns', { - taskManager: { - icon: 'assignment', - title: '任务列表', - onClick: function () { - Task.taskManagerLayer.toggleLayer(); - } - }, - downloadManager: { - icon: 'download', - title: '下载列表' - }, - setting: { - icon: 'settings', - title: '设置', - onClick: function () { - setting.getSidebar().toggle(); - } - } - }); - - AppNavbar.btn.groupAdd('task-runtime', { - backToTaskGen: { - icon: 'chevron-left', - title: '返回任务生成器', - onClick: function () { - Task.hide(); - } - }, - removeTask: { - icon: 'close', - title: '删除任务', - onClick: function () { - Task.getCurrent().remove(); - } - }, - showTaskInfo: { - icon: 'info', - title: '任务详情', - onClick: function () { - if (!Task.getCurrent()) - return; - - Task.getCurrent().showInfo(); - } - } - }).setMostLeft().hide(); - }, - // 标题设置 - setTitle: function (value, base64) { - if (typeof base64 === "boolean" && base64 === true) - value = Base64.decode(value); - - var navTitleSel = this.sel.navTitle; - $(navTitleSel).addClass('changing'); - setTimeout(function() { - $(navTitleSel) - .text(value) - .removeClass('changing'); - }, 100); - }, - // 标题获取 - getTitle: function () { - return $(this.sel.navTitle).text(); - } -}; - - -/** - * 导航栏按钮 - */ -window.AppNavbar.btn = { - sel: { - navBtns: '.top-nav-bar .nav-btns' - }, - groupList: {}, - // 按钮批量添加 - groupAdd: function (groupName, btnList) { - var btnGroup, btnGroupDom; - if (!this.getGroup(groupName)) { - // 创建新的按钮组对象 - btnGroup = {}; - btnGroupDom = $('
').appendTo(this.sel.navBtns); - // 设置按钮组显示在最左 - btnGroup.setMostLeft = function () { - btnGroupDom.insertBefore($(AppNavbar.btn.sel.navBtns+' .btn-group:first-child')); - return btnGroup; - }; - // 设置按钮组显示在最右 - btnGroup.setMostRight = function () { - btnGroupDom.insertAfter($(AppNavbar.btn.sel.navBtns+' .btn-group:last-child')); - return btnGroup; - }; - // 隐藏按钮组 - btnGroup.hide = function () { - btnGroupDom.hide(); - return btnGroup; - }; - // 获取 Dom - btnGroup.getDom = function () { - return btnGroupDom; - }; - // 显示 - btnGroup.show = function () { - btnGroup.getDom().show(); - return btnGroup; - }; - // 隐藏 - btnGroup.hide = function () { - btnGroup.getDom().hide(); - return btnGroup; - }; - // 添加图标 - btnGroup.btnList = {}; - btnGroup.addBtn = function (btnName, btnObj) { - btnGroup.btnList[btnName] = btnObj; - return btnObj; - }; - btnGroup.getBtn = function (btnName) { - if (!btnGroup.btnList[btnName]) return null; - return btnGroup.btnList[btnName]; - }; - this.groupList[groupName] = btnGroup; - } else { - btnGroup = this.getGroup(groupName); - btnGroupDom = btnGroup.getDom(); - } - - // 遍历在按钮组中添加每一个按钮 - $.each(btnList, function (btnName, value) { - var dom = $(''); - if (!!value['onClick']) dom.click(value['onClick']); - dom.appendTo(btnGroupDom); - dom.tooltip(); - var btnObj = {}; - btnObj.showBadge = function () { - dom.addClass('show-top-badge'); - return btnObj; - }; - btnObj.hideBadge = function () { - dom.removeClass('show-top-badge'); - return btnObj; - }; - btnObj.getDom = function () { - return dom; - }; - btnGroup.addBtn(btnName, btnObj); - }); - - return btnGroup; - }, - // 获取按钮组 - getGroup: function (groupName) { - if (!this.groupList.hasOwnProperty(groupName)) return null; - return this.groupList[groupName]; - }, - // 获取 按钮组 / 按钮 对象 - get: function (name) { - name = name.split('.'); - if (!!name[0] && !!name[1]) - return this.getGroup(name[0]).getBtn(name[1]); - if (!!name[0] && !name[1]) - return this.getGroup(name[0]); - return null; - } -}; - -/** - * 任务选择列表 - */ -(function () { - // 表单控件 - var Form = { - // 当前表单数据添加 - _currentInfoAdd: function (fieldName, label, inputTagId, validator) { - TaskGen.current.inputs[fieldName] = { - label: label, - inputSel: '#'+inputTagId - }; - // 验证器 - if (!!validator) - TaskGen.current.inputs[fieldName].validator = validator; - }, - // 文本框 - textInput: function (fieldName, label, defaultVal, validator) { - defaultVal = defaultVal || ''; - var tagId = 'TaskGen_'+fieldName; - var formGroup = $('
\n\n
').appendTo(TaskGen.sel.form); - var formInput = $('').appendTo(formGroup); - this._currentInfoAdd(fieldName, label, tagId, validator); - }, - // 数字框 - numberInput: function (fieldName, label, defaultVal, min, max) { - defaultVal = defaultVal || ''; - min = min || ''; - max = max || ''; - var tagId = 'TaskGen_'+fieldName; - var formGroup = $('
\n\n
').appendTo(TaskGen.sel.form); - var formInput = $('').appendTo(formGroup); - this._currentInfoAdd(fieldName, label, tagId); - }, - // 多行文本框 - textareaInput: function (fieldName, label, defaultVal, height) { - defaultVal = defaultVal || ''; - var tagId = 'TaskGen_'+fieldName; - var formGroup = $('
\n\n
').appendTo(TaskGen.sel.form); - var formInput = $('').appendTo(formGroup); - if (!!height) formInput.css('height', height); // 设置高度 - this._currentInfoAdd(fieldName, label, tagId); - }, - // 选择菜单 - selectInput: function (fieldName, label, values, selectValue) { - var tagId = 'TaskGen_'+fieldName; - var formGroup = $('
\n\n
').appendTo(TaskGen.sel.form); - var inputHtml = ''; - var formInput = $(inputHtml).appendTo(formGroup); - this._currentInfoAdd(fieldName, label, tagId); - } - }; - // 操作列表 - window.SpiderList = {}; - window.SpiderList.Business = { _NamespaceLabel: "电商" }; - window.SpiderList.Business.CollItemDescImg = { - label: "商品详情页图片解析", - genForm: function () { - Form.textInput('PageUrl', '详情页链接', '', inputValidators.isUrl); - Form.selectInput('PageType', '链接类型', { - "Tmall": "天猫", - "Taobao": "淘宝", - "Alibaba": "阿里巴巴", - "Suning": "苏宁易购", - "Gome": "国美在线" - }); - Form.selectInput('ImgType', '图片类型', { - "Thumb": "主图", - "Category": "分类图", - "Desc": "详情图" - }); - Form.selectInput('CollType', '采集模式', { - "collImgSrcUrl": "显示图片链接", - "collDownloadImgSrc": "显示图片链接 并 下载打包保存" - }); - } - }; - window.SpiderList.Business.TaobaoSellerColl = { - label: "淘宝店铺搜索卖家ID名采集", - genForm: function () { - Form.textInput('PageUrl', '店铺搜索页链接', '', inputValidators.isUrl); - Form.numberInput('CollBeginPage', '采集开始页码', 1, 1); - Form.numberInput('CollEndPage', '采集结束页码', undefined, 1); - Form.selectInput('IgnoreTmall', '忽略天猫卖家', { - "on": "开启", - "off": "关闭" - }); - } - }; - window.SpiderList.Business.TmallGxptInvite = { - label: "天猫供销平台分销商一键邀请", - genForm: function () { - Form.textareaInput('SellerId', '分销商ID名(一行一个)', undefined, 250); - } - }; - window.SpiderList.Business.TmallGxptInviteDelete = { - label: "天猫供销平台分销商一键撤回", - genForm: function () { - Form.numberInput('DeleteBeginPage', '撤回开始页码', 1, 1); - Form.numberInput('DeleteEndPage', '撤回结束页码', undefined, 1); - } - }; - window.SpiderList.Picture = { _NamespaceLabel: "图片" }; - window.SpiderList.Picture.Test = { - label: "开发测试 DEBUG...", - genForm: function () {} - }; - window.SpiderList.Debug = { _NamespaceLabel: "调试" }; - window.SpiderList.Debug.Default = { - label: "Default", - genForm: function () {} - }; -})(); - -/** - * Task Generator (任务生成器) - */ -window.TaskGen = { - sel: { - form: '.taskgen-form', - formToggle: '.taskgen-form-toggle', - formToggleDropdown: '.taskgen-form-toggle .namespace-dropdown', - formToggleBtns: '.taskgen-form-toggle .classname-btns' - }, - // 当前 - current: { - typeName: null, - inputs: {} - }, - // 初始化 - init: function () { - // 遍历列表 生成按钮 - var dropdownDom = $('
'), - dropdownSelectedDom = dropdownDom.find('.dropdown-selected'), - dropdownOptionDom = dropdownDom.find('.dropdown-option'); - var btnsDom = $('
'); - - dropdownDom.appendTo(this.sel.formToggle); - btnsDom.appendTo(this.sel.formToggle); - - var dropdownOptionShow = function () { - dropdownOptionDom.addClass('show'); - // 若点击其他地方 - setTimeout(function () { - $(document).bind('click.dropdown-option', function (e) { - if(!$(e.target).is('.dropdown-option') && !$(e.target).closest('.dropdown-option').length) { - dropdownOptionHide(); - } - }); - }, 20); - }; - var dropdownOptionHide = function () { - $(document).unbind('click.dropdown-option'); - dropdownOptionDom.removeClass('show'); - }; - dropdownSelectedDom.click(function () { - dropdownOptionShow(); - }); - - $.each(SpiderList, function (namespace, eachClass) { - var li = $('
  • '+eachClass._NamespaceLabel+'
  • '); - // 点击 li - li.click(function () { - // 按钮显示 - btnsDom.html(''); // 删除原有的所有按钮 - $.each(eachClass, function (classname, classInfo) { - if (classname.substr(0, 1) === '_') return; - var typeName = namespace + '.' + classname; - var btn = $('' + classInfo['label'] + '').appendTo(btnsDom); - // 选中之前点击过的按钮 - if (!!TaskGen.current.typeName && TaskGen.current.typeName === typeName) { - btnsDom.find('a').removeClass('active'); - $(btn).addClass('active'); - } - btn.click(function () { - // 表单生成 - TaskGen.formLoad(typeName); - // 按钮选中 - btnsDom.find('a').removeClass('active'); - $(this).addClass('active'); - }); - }); - dropdownSelectedDom.text($(this).text()); - dropdownSelectedDom.attr('data-namespace', namespace); - // 选中当前 li - dropdownOptionDom.find('li').removeClass('selected'); - $(this).addClass('selected'); - // 取消显示 dropdown-option - dropdownOptionHide(); - // 当前 li 置顶 - // $(this).insertBefore(dropdownOptionDom.find('li:first-child')); - }); - li.appendTo(dropdownOptionDom); - }); - - // 打开第一个任务生成器 - dropdownOptionDom.find('li:first-child').click(); - btnsDom.find('a:first-child').click(); - }, - // 分析 TypeName - spiderListGet: function (typeNameStr) { - var typeName = typeNameStr.split('.') || null; - if (!typeName || !typeName[0] || !typeName[1]) return null; - var namespace = typeName[0], - classname = typeName[1]; - if (!SpiderList.hasOwnProperty(namespace) || !SpiderList[namespace].hasOwnProperty(classname)) return null; - return SpiderList[namespace][classname]; - }, - // 表单装载 - formLoad: function (typeName) { - // 点击操作按钮事件 - if (!this.spiderListGet(typeName)) - throw ('SpiderList 中没有 ' + typeName + ',无法创建表单!'); - - var spider = this.spiderListGet(typeName); - var formDom = $(this.sel.form); - - // 清除当前表单 - formDom.html(''); - // 清除当前数据 - this.current.typeName = null; - this.current.inputs = {}; - - // 装入新数据 - this.current.typeName = typeName; - // 执行表单创建 - spider.genForm(); - // 提交按钮 - var submitBtn = $('
    \n\n
    ') - .appendTo(formDom); - - submitBtn.click(function () { - if (!TaskGen.formCheck()) - return false; - - Task.createTask(typeName, spider.label, formDom.serializeArray()); - - return false; - }); - }, - // 表单提交检验 - formCheck: function () { - var isInputAllRight = true; - $.each(TaskGen.current.inputs, function (i, obj) { - if (!obj.inputSel || $(obj.inputSel).length === 0) - throw ('表单输入元素 '+i+' 的 Selector 无效'); - - var inputSel = obj.inputSel, - inputDom = $(inputSel), - inputVal = inputDom.val().trim(); - - if (inputVal === '') { - inputDom.focus(); - isInputAllRight = false; - return false; - } - - // 验证器 - if (!!obj.validator && !obj.validator(inputVal)) { - inputDom.addClass('has-error').focus(); - inputDom.bind('input propertychange', function() { - if (obj.validator($(this).val().trim())) $(this).unbind('input propertychange').removeClass('has-error'); - }); - isInputAllRight = false; - return false; - } - }); - - return isInputAllRight; - } -}; - -window.Task = { - sel: { - runtime: '.task-runtime' - }, - // 任务列表 - list: {}, - // 当前显示的任务ID - currentDisplayedId: null, - // 创建任务 - createTask: function (typeName, classLabel, parmsObj) { - var taskId = new Date().getTime().toString(); - var runtimeSel = this.sel.runtime; - // 创建元素 - $('